Skip to content

Commit 81682fe

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 of the callback. This change ensures that setReadyState() *and* the_onCloseCallback() are executed by a single thread till completion, by taking a new mutex that's used to synchronize access to _readyState. 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 81682fe

File tree

2 files changed

+6
-1
lines changed

2 files changed

+6
-1
lines changed

ixwebsocket/IXWebSocketTransport.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,14 @@ namespace ix
200200

201201
WebSocketTransport::ReadyState WebSocketTransport::getReadyState() const
202202
{
203+
std::lock_guard<std::mutex> lock(_setReadyStateMutex);
203204
return _readyState;
204205
}
205206

206207
void WebSocketTransport::setReadyState(ReadyState readyState)
207208
{
209+
std::lock_guard<std::mutex> lock(_setReadyStateMutex);
210+
208211
// No state change, return
209212
if (_readyState == readyState) return;
210213

ixwebsocket/IXWebSocketTransport.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,9 @@ namespace ix
184184
std::mutex _socketMutex;
185185

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

189191
OnCloseCallback _onCloseCallback;
190192
std::string _closeReason;

0 commit comments

Comments
 (0)