···775775 }
776776777777 fn cleanupConn(self: *Self, hc: *HandlerConn(H)) void {
778778- if (hc.reader) |*reader| {
779779- if (self.small_buffer_pool) |*sbp| {
780780- sbp.release(reader.static);
781781- } else {
782782- self.allocator.free(reader.static);
778778+ {
779779+ hc.cleanup.lock();
780780+ defer hc.cleanup.unlock();
781781+ if (hc.reader) |*reader| {
782782+ if (self.small_buffer_pool) |*sbp| {
783783+ sbp.release(reader.static);
784784+ } else {
785785+ self.allocator.free(reader.static);
786786+ }
787787+ hc.reader = null;
783788 }
784789 }
785790 self.conn_manager.cleanup(hc);
···792797793798 // called for each hc when shutting down
794799 fn shutdownCleanup(self: *Self, hc: *HandlerConn(H)) void {
800800+ hc.cleanup.lock();
801801+ defer hc.cleanup.unlock();
795802 if (hc.reader) |*reader| {
796803 if (self.small_buffer_pool == null) {
797804 self.allocator.free(reader.static);
798805 }
806806+ hc.reader = null;
799807 }
800808 }
801809 };
···10861094 reader: ?Reader,
10871095 socket: posix.socket_t, // denormalization from conn.stream.handle
10881096 handshake: ?*Handshake.State,
10971097+ cleanup: Thread.Mutex = .{},
10891098 compression: ?Compression = null,
10901099 next: ?*HandlerConn(H) = null,
10911100 prev: ?*HandlerConn(H) = null,
···12721281 // This is sloppy and leaves things in an unrecoverable state. To keep
12731282 // things clean, we should call self.cleanup(hc) on each entry in the list
12741283 // but that does a bunch of things we don't need if we know that we're
12751275- // shutting down - like returning data to the pools, nd popping items
12841284+ // shutting down - like returning data to the pools, and popping items
12761285 // out of the list.
12771286 fn shutdownList(head: ?*HandlerConn(H), worker: anytype) void {
12781287 var next_node = head;