Explorar o código

Fix WebSocket pings being sent early on spurious wakeups

The heartbeat thread waited on ping_cv_ without a predicate, so a
spurious wakeup ended the wait early and sent a ping before
ping_interval_sec_ had elapsed. With max_missed_pongs enabled, the
early ping also counted toward the pong timeout.

Pass a predicate to wait_for so that the wait only ends when the
interval elapses or the connection is closed.

Reported in #2612.
yhirose hai 4 días
pai
achega
438319cfcb
Modificáronse 1 ficheiros con 3 adicións e 1 borrados
  1. 3 1
      httplib.h

+ 3 - 1
httplib.h

@@ -22828,7 +22828,9 @@ inline void WebSocket::start_heartbeat() {
   ping_thread_ = std::thread([this]() {
     std::unique_lock<std::mutex> lock(ping_mutex_);
     while (!closed_) {
-      ping_cv_.wait_for(lock, std::chrono::seconds(ping_interval_sec_));
+      // The predicate keeps a spurious wakeup from sending a ping early
+      ping_cv_.wait_for(lock, std::chrono::seconds(ping_interval_sec_),
+                        [this]() { return closed_.load(); });
       if (closed_) { break; }
       // If the peer has failed to respond to the previous pings, give up.
       // RFC 6455 does not define a pong-timeout mechanism; this is an