···662662 }
663663 thread_pool.spawn(.{ self, now, conn });
664664 },
665665+ // Stable tombstone for WebSocket userdata whose fd
666666+ // was closed on a pool thread. A queued kernel event
667667+ // may still carry this pointer; it must be ignored.
668668+ .retired => continue,
665669 },
666670 .shutdown => return,
667671 }
···887891 // here is unsafe because accept may already have reused that fd
888892 // for another connection. In that race, this DEL removed the new
889893 // connection's read monitor and left it stuck in request_list.
890890- // The graveyard's job is only to defer memory reclamation until
891891- // every pointer in the current event batch has been consumed.
894894+ // More importantly, close happens on another thread, so the
895895+ // reactor cannot prove that a readiness notification carrying
896896+ // this userdata pointer is not still queued beyond the current
897897+ // epoll_wait batch. Never recycle websocket Conn userdata: an
898898+ // old notification must continue to point at retired websocket
899899+ // state, never at a newly accepted HTTP connection (the ABA
900900+ // that cross-wired responses in production). MemoryPool.deinit
901901+ // releases these tiny stable-lifetime nodes at server shutdown.
892902 self.websocket.cleanupConn(hc);
903903+ conn.protocol = .{ .retired = {} };
893904 self.len -= 1;
894894- self.conn_mem_pool.destroy(conn);
895905 }
896906 return released;
897907 }
···905915 switch (conn.protocol) {
906916 .http => |http_conn| self.processHTTPData(now, conn, thread_buf, http_conn),
907917 .websocket => |hc| self.processWebsocketData(conn, thread_buf, hc),
918918+ .retired => {},
908919 }
909920 }
910921···16611672 protocol: union(enum) {
16621673 http: *HTTPConn,
16631674 websocket: *ws.HandlerConn(WSH),
16751675+ retired: void,
16641676 },
1665167716661678 // Node in a List(WSH). List is [obviously] intrusive.
···16891701 switch (self.protocol) {
16901702 .http => |http_conn| posix.close(http_conn.stream.socket.handle),
16911703 .websocket => |hc| hc.conn.close(.{}) catch {},
17041704+ .retired => {},
16921705 }
16931706 }
16941707···16961709 return switch (self.protocol) {
16971710 .http => |hc| hc.stream.socket.handle,
16981711 .websocket => |hc| hc.socket,
17121712+ .retired => unreachable,
16991713 };
17001714 }
17011715