Skip to content

Commit 80e6c4f

Browse files
committed
IXWebSocketTransport::setReadyState(): Run under lock
When setReadyState(CLOSED) is executed from two different threads (the server's thread, detecting a close trying to receive and a separate sending thread), there is a race where both see _readyState as non-CLOSED and both execute the _onCloseCallback(). Worse, the server's thread might be returning from ->run(), unsetting the callback, while the other thread is still about to call the _onCloseCallback(), resulting in a crash rather than "just" a duplicate invocation. This change ensures that setReadyState() *and* the_onCloseCallback() are executed by a single thread till completion. I was tempted to remove the std::atomic<> for _readyState, but left it assuming it's still good having for getReadyState(). I've first tried _readyState.exchange() which seemed promising, but still crashed once in a while as racing threads do not wait for the _onCloseCallback() to complete.
1 parent 8115594 commit 80e6c4f

File tree

2 files changed

+4
-0
lines changed

2 files changed

+4
-0
lines changed

ixwebsocket/IXWebSocketTransport.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ namespace ix
205205

206206
void WebSocketTransport::setReadyState(ReadyState readyState)
207207
{
208+
std::lock_guard<std::mutex> lock(_setReadyStateMutex);
209+
208210
// No state change, return
209211
if (_readyState == readyState) return;
210212

ixwebsocket/IXWebSocketTransport.h

+2
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ namespace ix
185185

186186
// Hold the state of the connection (OPEN, CLOSED, etc...)
187187
std::atomic<ReadyState> _readyState;
188+
// Mutex to prevent racing in setReadyState()
189+
std::mutex _setReadyStateMutex;
188190

189191
OnCloseCallback _onCloseCallback;
190192
std::string _closeReason;

0 commit comments

Comments
 (0)