feat(quic): ClientQUIC::OnClosed tells the owner the connection is over
A ListenerQUIC hands each accepted connection to its callback as a heap-allocated ClientQUIC the callback owns, and nothing said when to delete it: the SHUTDOWN_COMPLETE handler closed the msquic handle of a connection the peer or the idle timeout ended, but the object stayed, so a server either leaked its peers or deleted them blind, and one still alive at exit holds msquic's registration open until its idle timeout. OnClosed(callback) is told once when the connection has shut down for any reason but this object's destruction: the peer closed it, the idle timeout or a transport error ended it, or Stop() was called. It runs on the msquic worker, in the SHUTDOWN_COMPLETE handler, after that handler has claimed and closed the handle, so deleting the ClientQUIC from inside it is safe: ~ClientQUIC then finds no handle to claim and waits for nothing. Delivering it there, rather than as a pool task, keeps it independent of a pool the host shares and possibly saturates; the cost is the usual worker rule, which the interface spells out (no blocking, no *Sync call, no deleting another ClientQUIC from inside it). A callback set after the close, which happens when the peer goes before a ListenerQUIC's connectCallback runs, fires as a pool task instead, never from inside OnClosed, where the caller is still using the object. Its state is a shared CloseNotice rather than part of the Impl, since the handler fires it after giving up the handle, when ~ClientQUIC on another thread no longer waits for the worker and may free the Impl. The rules are std::stop_callback's: ~ClientQUIC marks the owner gone first, after which the callback never starts; one already running on another thread is waited for, so the owner may free what it uses as soon as the destructor returns; one on the destructor's own thread, a callback deleting its connection, is not. The handler takes the handle and the notice under one lock, so the destructor cannot slip between. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
be55036b18
commit
f0769838e5
3 changed files with 136 additions and 7 deletions
|
|
@ -197,6 +197,7 @@ extern "C" Configuration CrafterBuildProject(std::span<const std::string_view> a
|
|||
cfg.AddTest("ShouldFallbackUnknownRoutes").Dependencies({ &cfg });
|
||||
cfg.AddTest("ShouldHonourQUICSettings").Dependencies({ &cfg });
|
||||
cfg.AddTest("ShouldNotDropEarlyStreams").Dependencies({ &cfg });
|
||||
cfg.AddTest("ShouldNotifyClosedConnectionQUIC").Dependencies({ &cfg });
|
||||
cfg.AddTest("ShouldSend").Dependencies({ &cfg });
|
||||
cfg.AddTest("ShouldSendRecieveHTTP").Dependencies({ &cfg });
|
||||
cfg.AddTest("ShouldSendRecieveKeepaliveHTTP").Dependencies({ &cfg });
|
||||
|
|
|
|||
Loading…
Reference in a new issue