Loading src/quic.cpp +15 −1 Original line number Diff line number Diff line Loading @@ -2795,11 +2795,25 @@ void quic::pumpNetwork(int flags) { // Loss detection + PTO probes: retransmit lost/stale packets so the // peer can make progress even when the caller is not sending new data. // Unlike the checkLossAndRetransmit() calls after processing an ACK // frame or a pumpIncoming() batch (which run because something new // just happened, so they always run immediately), this call site is // purely opportunistic polling — a caller looping on pumpNetwork() can // invoke it enormously more often than the RTT/PTO-scale checks inside // are useful (measured ~1 call per 3us under load, vs. PTO thresholds // of tens of ms at minimum: see the +0.025s term and 0.5s initial _rto // above). Throttle only *this* call site so a busy poll loop doesn't // pay for a full _sent_packets scan on every iteration; the ACK- and // batch-triggered call sites are untouched and still fire promptly. { std::lock_guard<std::recursive_mutex> lock(quic_mtx()); auto now = std::chrono::steady_clock::now(); if (now - _last_pump_loss_scan >= _pump_loss_scan_interval) { _last_pump_loss_scan = now; checkLossAndRetransmit(); } } } // ============================================================================ // Stream Data Receive (for specific stream) Loading src/socket.h +9 −0 Original line number Diff line number Diff line Loading @@ -1040,6 +1040,15 @@ namespace netplus { static constexpr double TIME_THRESHOLD = 9.0/8; // RFC 9002 kTimeThreshold int _pto_count = 0; // PTO back-off counter (RFC 9002 §6.2) // Throttle for pumpNetwork()'s opportunistic checkLossAndRetransmit() // call only (see pumpNetwork) — NOT used by the ACK-frame or // pumpIncoming() call sites, which must stay untouched since they // run precisely because something new arrived. Per-instance so // servicing multiple connections on one thread can't make one // connection's polling suppress another's. std::chrono::steady_clock::time_point _last_pump_loss_scan{}; static constexpr std::chrono::microseconds _pump_loss_scan_interval{50}; // Flow control batching: avoid sending duplicate MAX_DATA/MAX_STREAM_DATA bool _pending_max_data = false; uint64_t _pending_max_data_value = 0; Loading Loading
src/quic.cpp +15 −1 Original line number Diff line number Diff line Loading @@ -2795,11 +2795,25 @@ void quic::pumpNetwork(int flags) { // Loss detection + PTO probes: retransmit lost/stale packets so the // peer can make progress even when the caller is not sending new data. // Unlike the checkLossAndRetransmit() calls after processing an ACK // frame or a pumpIncoming() batch (which run because something new // just happened, so they always run immediately), this call site is // purely opportunistic polling — a caller looping on pumpNetwork() can // invoke it enormously more often than the RTT/PTO-scale checks inside // are useful (measured ~1 call per 3us under load, vs. PTO thresholds // of tens of ms at minimum: see the +0.025s term and 0.5s initial _rto // above). Throttle only *this* call site so a busy poll loop doesn't // pay for a full _sent_packets scan on every iteration; the ACK- and // batch-triggered call sites are untouched and still fire promptly. { std::lock_guard<std::recursive_mutex> lock(quic_mtx()); auto now = std::chrono::steady_clock::now(); if (now - _last_pump_loss_scan >= _pump_loss_scan_interval) { _last_pump_loss_scan = now; checkLossAndRetransmit(); } } } // ============================================================================ // Stream Data Receive (for specific stream) Loading
src/socket.h +9 −0 Original line number Diff line number Diff line Loading @@ -1040,6 +1040,15 @@ namespace netplus { static constexpr double TIME_THRESHOLD = 9.0/8; // RFC 9002 kTimeThreshold int _pto_count = 0; // PTO back-off counter (RFC 9002 §6.2) // Throttle for pumpNetwork()'s opportunistic checkLossAndRetransmit() // call only (see pumpNetwork) — NOT used by the ACK-frame or // pumpIncoming() call sites, which must stay untouched since they // run precisely because something new arrived. Per-instance so // servicing multiple connections on one thread can't make one // connection's polling suppress another's. std::chrono::steady_clock::time_point _last_pump_loss_scan{}; static constexpr std::chrono::microseconds _pump_loss_scan_interval{50}; // Flow control batching: avoid sending duplicate MAX_DATA/MAX_STREAM_DATA bool _pending_max_data = false; uint64_t _pending_max_data_value = 0; Loading