Summary
Reactor.Teardown frees the ring, the provided-buffer slabs, the UDP blocks and the timespecs, and CloseAcceptedTcpSockets closes the accepted descriptors - but neither _pool nor the TcpConnection objects still in _connections are disposed. Each one owns a NativeMemory.AlignedAlloc'd write slab (WriteSlabSize, 16 KiB by default; more when grown, plus the iovec/msghdr in Segmented mode and the per-connection buffer ring in incremental mode), and TcpConnection has no finalizer, so that memory is unreachable after Stop().
Up to PoolMax x WriteSlabSize per reactor per stop - 16 MiB at the defaults. It matters for hosts that start and stop many servers in one process, which is exactly what the test suites do.
Where
src/ioxide/Reactor/Reactor.Runner.cs Teardown()
src/ioxide/Reactor/Transport/Tcp/Reactor.Tcp.cs CloseAcceptedTcpSockets() - closes the fd, drops the object
src/ioxide/Connection/Tcp/TcpConnection.cs Dispose() - only reached from Recycle when the pool is already full
Fix
In Teardown, after the ring fd is closed (so no SEND can still reference a slab): Dispose() every non-null _connections[fd] and drain _pool through Dispose(). DisposeIncremental goes with them.
Summary
Reactor.Teardownfrees the ring, the provided-buffer slabs, the UDP blocks and the timespecs, andCloseAcceptedTcpSocketscloses the accepted descriptors - but neither_poolnor theTcpConnectionobjects still in_connectionsare disposed. Each one owns aNativeMemory.AlignedAlloc'd write slab (WriteSlabSize, 16 KiB by default; more when grown, plus the iovec/msghdr inSegmentedmode and the per-connection buffer ring in incremental mode), andTcpConnectionhas no finalizer, so that memory is unreachable afterStop().Up to
PoolMax x WriteSlabSizeper reactor per stop - 16 MiB at the defaults. It matters for hosts that start and stop many servers in one process, which is exactly what the test suites do.Where
src/ioxide/Reactor/Reactor.Runner.csTeardown()src/ioxide/Reactor/Transport/Tcp/Reactor.Tcp.csCloseAcceptedTcpSockets()- closes the fd, drops the objectsrc/ioxide/Connection/Tcp/TcpConnection.csDispose()- only reached fromRecyclewhen the pool is already fullFix
In
Teardown, after the ring fd is closed (so no SEND can still reference a slab):Dispose()every non-null_connections[fd]and drain_poolthroughDispose().DisposeIncrementalgoes with them.