From ac7cd817df894172baa63cff0c5c8ab812c307f6 Mon Sep 17 00:00:00 2001 From: siddiqui irshad Date: Wed, 28 Oct 2026 02:09:52 +0530 Subject: [PATCH] Process closed sockets pending destruction before polling in PollRawUDPSockets (#458) When a socket is closed on another thread, InternalAddToCleanupQueue sets m_callback.m_fnCallback = nullptr to mark it pending destruction and wakes the service thread. If PollRawUDPSockets runs before ProcessDeferredOperations has executed ProcessPendingDestroyClosedRawUDPSockets, the DBGFLAG_ASSERT sanity loop trips on pSock->m_callback.m_fnCallback. Calling ProcessPendingDestroyClosedRawUDPSockets at the start of PollRawUDPSockets ensures closed sockets are destroyed and removed from s_vecRawSockets before the sanity check and before polling. --- .../clientlib/steamnetworkingsockets_socketthread.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_socketthread.cpp b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_socketthread.cpp index 5a43c219..7be55ccb 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_socketthread.cpp +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_socketthread.cpp @@ -2602,6 +2602,9 @@ static bool PollRawUDPSockets( int nMaxTimeoutMS, bool bManualPoll ) // and we assume that it will have locked the lock exactly once. AssertGlobalLockHeldExactlyOnce(); + // Clean up any sockets that were closed and marked pending destruction before polling + ProcessPendingDestroyClosedRawUDPSockets(); + // Sanity check all of our sockets are alive #ifdef DBGFLAG_ASSERT for ( CRawUDPSocketImpl *pSock: s_vecRawSockets )