Loading src/quic.cpp +14 −2 Original line number Diff line number Diff line Loading @@ -3094,8 +3094,20 @@ void quic::accept(std::unique_ptr<socket>& csock, bool nonblock) { // csock. QUIC connections share the parent socket and are routed via // accept(). csock = nullptr; flush_pending_app(); // don't drop already-scanned packets from this cycle return; // New connection created — exit drain loop // Fall through to the next datagram in this batch instead of returning // here: recvBatchAddrViews() already pulled every datagram in the // current batch out of the kernel socket queue, so returning early // silently dropped any later datagram in the *same* batch -- most // importantly another concurrent client's own new-connection Initial // packet, which the kernel no longer has queued for a subsequent // select()/recv to find. This is why quic_concurrent_test failed // reproducibly even with just 2 simultaneous connections: whenever two // clients' Initial packets landed in the same recv batch, only the // first was ever processed. Every other early-exit in this loop already // uses `continue` for exactly this reason; this was the one outlier. // flush_pending_app() still only runs once, at the end of the full // batch below, so packets for existing connections keep batching // together instead of flushing prematurely on every new connection. } // end msg_i loop Loading Loading
src/quic.cpp +14 −2 Original line number Diff line number Diff line Loading @@ -3094,8 +3094,20 @@ void quic::accept(std::unique_ptr<socket>& csock, bool nonblock) { // csock. QUIC connections share the parent socket and are routed via // accept(). csock = nullptr; flush_pending_app(); // don't drop already-scanned packets from this cycle return; // New connection created — exit drain loop // Fall through to the next datagram in this batch instead of returning // here: recvBatchAddrViews() already pulled every datagram in the // current batch out of the kernel socket queue, so returning early // silently dropped any later datagram in the *same* batch -- most // importantly another concurrent client's own new-connection Initial // packet, which the kernel no longer has queued for a subsequent // select()/recv to find. This is why quic_concurrent_test failed // reproducibly even with just 2 simultaneous connections: whenever two // clients' Initial packets landed in the same recv batch, only the // first was ever processed. Every other early-exit in this loop already // uses `continue` for exactly this reason; this was the one outlier. // flush_pending_app() still only runs once, at the end of the full // batch below, so packets for existing connections keep batching // together instead of flushing prematurely on every new connection. } // end msg_i loop Loading