Commit 57d56372 authored by jan.koester's avatar jan.koester
Browse files

quic fix

parent 13ccbc15
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -1985,7 +1985,17 @@ void quic::accept(std::unique_ptr<socket>& csock, bool nonblock) {
    std::map<std::shared_ptr<quic>, std::vector<std::pair<const uint8_t*, size_t>>> pending_app_pkts;
    auto flush_pending_app = [&]() {
        for (auto& [existing, pkts] : pending_app_pkts) {
            std::unique_lock<std::recursive_mutex> child_lock(existing->quic_mtx());
            // try_lock, not block: this runs on the shared accept/drain
            // loop (see the concurrency note above — normally one thread,
            // but never more than one at a time for a given listener), so
            // blocking here to wait out a connection that's busy elsewhere
            // (e.g. mid-transfer) stalls accepting brand-new connections
            // and processing every OTHER existing connection's traffic
            // too, not just this one. QUIC's own loss detection retransmits
            // whatever we skip, so dropping it now and picking it up on a
            // later drain cycle is safe and far cheaper than blocking.
            std::unique_lock<std::recursive_mutex> child_lock(existing->quic_mtx(), std::try_to_lock);
            if (!child_lock.owns_lock()) continue;
            existing->processApplicationPacketsBatch(pkts);

            if (existing->_handshake_complete &&
@@ -2164,8 +2174,17 @@ void quic::accept(std::unique_ptr<socket>& csock, bool nonblock) {

            // Fall through to create a new connection
        } else {
            // Active connection
            std::unique_lock<std::recursive_mutex> child_lock(existing->quic_mtx());
            // Active connection. try_lock, not block — this long-header
            // packet (a mid-handshake retransmission, typically) is handled
            // inline rather than deferred via pending_app_pkts, so blocking
            // here stalls this accept() call at the current datagram,
            // before it can ever reach later ones in the same batch —
            // including a brand-new connection's Initial packet. A busy
            // connection (e.g. mid-transfer elsewhere) must never be able
            // to stall new connections from being accepted at all. QUIC's
            // own loss detection retransmits whatever we skip here.
            std::unique_lock<std::recursive_mutex> child_lock(existing->quic_mtx(), std::try_to_lock);
            if (!child_lock.owns_lock()) continue;
            existing->processIncomingPacket(dgram.data(), dgram.size());

            // Flush child's pending flow control frames