@@ -118,6 +118,15 @@ class CTrivialSignalingClient : public ITrivialSignalingClient
118118 SOCKET m_sock;
119119 std::string m_sBufferedData;
120120
121+ // Lightweight progress telemetry to diagnose stalls in signaling receive/dispatch.
122+ SteamNetworkingMicroseconds m_usecLastHeartbeat;
123+ uint64 m_nPollCalls;
124+ uint64 m_nBytesRecv;
125+ uint64 m_nLinesParsed;
126+ uint64 m_nDispatchCalls;
127+ uint64 m_nDispatchFailures;
128+ uint64 m_usecDispatch;
129+
121130 void CloseSocket ()
122131 {
123132 if ( m_sock != INVALID_SOCKET )
@@ -166,6 +175,13 @@ class CTrivialSignalingClient : public ITrivialSignalingClient
166175 {
167176 memcpy ( &m_adrServer, adrServer, adrServerSize );
168177 m_sock = INVALID_SOCKET;
178+ m_usecLastHeartbeat = 0 ;
179+ m_nPollCalls = 0 ;
180+ m_nBytesRecv = 0 ;
181+ m_nLinesParsed = 0 ;
182+ m_nDispatchCalls = 0 ;
183+ m_nDispatchFailures = 0 ;
184+ m_usecDispatch = 0 ;
169185
170186 // Save off our identity
171187 SteamNetworkingIdentity identitySelf; identitySelf.Clear ();
@@ -219,6 +235,15 @@ class CTrivialSignalingClient : public ITrivialSignalingClient
219235
220236 virtual void Poll () override
221237 {
238+ ++m_nPollCalls;
239+ int nBytesRecvThisPoll = 0 ;
240+ int nLinesParsedThisPoll = 0 ;
241+ int nDispatchCallsThisPoll = 0 ;
242+ int nDispatchFailuresThisPoll = 0 ;
243+ SteamNetworkingMicroseconds usecDispatchThisPoll = 0 ;
244+ size_t nSendQueueSizeSnapshot = 0 ;
245+ bool bSocketValidSnapshot = false ;
246+
222247 // Drain the socket into the buffer, and check for reconnecting
223248 sockMutex.lock ();
224249 if ( m_sock == INVALID_SOCKET )
@@ -249,6 +274,7 @@ class CTrivialSignalingClient : public ITrivialSignalingClient
249274 }
250275
251276 m_sBufferedData.append ( buf, r );
277+ nBytesRecvThisPoll += r;
252278 }
253279 }
254280
@@ -279,6 +305,9 @@ class CTrivialSignalingClient : public ITrivialSignalingClient
279305 }
280306 }
281307
308+ nSendQueueSizeSnapshot = m_queueSend.size ();
309+ bSocketValidSnapshot = ( m_sock != INVALID_SOCKET );
310+
282311 // Release the lock now. See the notes below about why it's very important
283312 // to release the lock early and not hold it while we try to dispatch the
284313 // received callbacks.
@@ -297,6 +326,7 @@ class CTrivialSignalingClient : public ITrivialSignalingClient
297326 size_t spc = m_sBufferedData.find ( ' ' );
298327 if ( spc != std::string::npos && spc < l )
299328 {
329+ ++nLinesParsedThisPoll;
300330
301331 // Hex decode the payload. As it turns out, we actually don't
302332 // need the sender's identity. The payload has everything needed
@@ -369,12 +399,44 @@ class CTrivialSignalingClient : public ITrivialSignalingClient
369399 // To process this call, SteamnetworkingSockets will need take its own internal lock.
370400 // That lock may be held by another thread that is asking you to send a signal! So
371401 // be warned that deadlocks are a possibility here.
372- m_pSteamNetworkingSockets->ReceivedP2PCustomSignal ( data.c_str (), (int )data.length (), &context );
402+ SteamNetworkingMicroseconds usecDispatchStart = SteamNetworkingUtils ()->GetLocalTimestamp ();
403+ TEST_Printf ( " Signaling dispatch begin: payload=%d buffered=%zu\n " , (int )data.length (), m_sBufferedData.size () );
404+ bool bOK = m_pSteamNetworkingSockets->ReceivedP2PCustomSignal ( data.c_str (), (int )data.length (), &context );
405+ SteamNetworkingMicroseconds usecDispatchElapsed = SteamNetworkingUtils ()->GetLocalTimestamp () - usecDispatchStart;
406+ ++nDispatchCallsThisPoll;
407+ usecDispatchThisPoll += usecDispatchElapsed;
408+ if ( !bOK )
409+ ++nDispatchFailuresThisPoll;
410+ TEST_Printf ( " Signaling dispatch end: ok=%d elapsed=%.3fms\n " , bOK ? 1 : 0 , usecDispatchElapsed * 1e-3 );
373411 }
374412
375413next_message:
376414 m_sBufferedData.erase ( 0 , l+1 );
377415 }
416+
417+ m_nBytesRecv += nBytesRecvThisPoll;
418+ m_nLinesParsed += nLinesParsedThisPoll;
419+ m_nDispatchCalls += nDispatchCallsThisPoll;
420+ m_nDispatchFailures += nDispatchFailuresThisPoll;
421+ m_usecDispatch += usecDispatchThisPoll;
422+
423+ SteamNetworkingMicroseconds usecNow = SteamNetworkingUtils ()->GetLocalTimestamp ();
424+ if ( m_usecLastHeartbeat == 0 || usecNow - m_usecLastHeartbeat >= 1000000 )
425+ {
426+ m_usecLastHeartbeat = usecNow;
427+ TEST_Printf (
428+ " Signaling poll heartbeat: polls=%llu recv_bytes=%llu parsed_lines=%llu dispatch_calls=%llu dispatch_failures=%llu dispatch_ms=%.3f sock_valid=%d sendq=%zu buffered=%zu\n " ,
429+ (unsigned long long )m_nPollCalls,
430+ (unsigned long long )m_nBytesRecv,
431+ (unsigned long long )m_nLinesParsed,
432+ (unsigned long long )m_nDispatchCalls,
433+ (unsigned long long )m_nDispatchFailures,
434+ m_usecDispatch * 1e-3 ,
435+ bSocketValidSnapshot ? 1 : 0 ,
436+ nSendQueueSizeSnapshot,
437+ m_sBufferedData.size ()
438+ );
439+ }
378440 }
379441
380442 virtual void Release () override
0 commit comments