-
Notifications
You must be signed in to change notification settings - Fork 211
IXWebSocketTransport::setReadyState(): Run under lock #540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IXWebSocketTransport::setReadyState(): Run under lock #540
Conversation
|
Can you make the getReadyState use the mutex as well, and stop using an atomic ? Having a mutex AND an atomic seems weird. |
Thanks for the feedback. Done and re-pushed. |
|
The change looks simple, but all the thread sanitizer checks are not red .... |
|
Do you have access to a mac machine ? |
|
It's failing on Linux, too. Sorry, it's due to unprotected
Looking at the new diff, going back might be an option IMO and not all that weird: The mutex prevents concurrent execution of |
|
Alright then ... let's go back to your original idea, but do you mind adding a small comment explaining why we're doing things that way ? |
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 introducing a new _setReadyStateMutex instance held during setReadyState() execution.
Done. Feel free to word-smith during/after the merge. |
|
Hello @bsergean - friendly ping whether you'd consider merging this, or would rather have something changed with this PR? We're currently using a fork of IXWebSocket but would prefer to switch to your repo again :-) |
|
Thanks I did run the PR checks one last time. They don't run automatically for some reason. |
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.
Closes #539