ShouldRecieveByCallbackQUIC, seventeen checks. Bytes and a FIN that came
before OnRecieve are delivered by it before it returns. Registered while
1000 KiB keep arriving, with the first callbacks slowed to widen the
window and an echo sent from inside onData, every byte arrives in order
and no two of the stream's callbacks, onSent included, overlap; the
echo comes back whole. With every pool worker parked, 256 KiB goes out
and comes back by callback and SendAsync alone. The peer's Abort() and
a lost connection each end the stream not clean, once. Abort() from
inside onData caps a 1 MiB upload: no onData after it, onEnd(false),
and the peer's receive side ends while its next send is refused. A
wrapper destroyed inside its own onEnd, or moved while bytes flow,
breaks nothing; one destroyed on another thread mid-flow has no
callback run once its destructor returned. A second OnRecieve throws,
and a stream that cannot receive, or none, gets onEnd(false) at once.
With the serialisation disabled the overlap and order checks fail every
run; with Unregister's wait removed the destroyed-wrapper check fails
in most.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>