-
Notifications
You must be signed in to change notification settings - Fork 36.2k
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
Fix CCheckQueue IsIdle (potential) race condition #9495
Conversation
@@ -185,8 +182,7 @@ class CCheckQueueControl | |||
{ | |||
// passed queue is supposed to be unused, or NULL | |||
if (pqueue != NULL) { | |||
bool isIdle = pqueue->IsIdle(); | |||
assert(isIdle); | |||
ENTER_CRITICAL_SECTION(pqueue->ControlMutex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you do this as a unique_lock field inside CCheckQueueControl (so we don't need to rely on an explicit destructor to be correct)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately this is the "easiest" way to take care of this given that we want debug order & the CMutex class has no default constructor/moveable semantics. Certainly can be fixed to RAII easily later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood. Let's improve that in a separate PR later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK 958ee1d3d844d1f2f07b271ad7ed9bb117e5a766 with one nit:
Would suggest deleting the CCheckQueueControl default copy constructor and copy operator and making the pqueue member const, to give more assurance that the ENTER/LEAVE calls will always be paired.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK 2a58f73601ad36d0531fe9e69e1affd9229d8b96
src/checkqueue.h
Outdated
if (pqueue != NULL) { | ||
ENTER_CRITICAL_SECTION(pqueue->ControlMutex); | ||
} | ||
CCheckQueueControl<T>() = delete; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I think you can drop the <T>
2a58f73
to
020acd8
Compare
Squashed and addressed @ryanofsky's nit about template args in constructors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK
src/checkqueue.h
Outdated
CCheckQueueControl& operator=(const CCheckQueueControl&) = delete; | ||
explicit CCheckQueueControl(CCheckQueue<T> * const pqueueIn) : pqueue(pqueueIn), fDone(false) | ||
{ | ||
// passed queue is supposed to be unused, or NULL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird indendation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops -- somehow, my expandtab and tabstop=4 got unset.
020acd8
to
f5daff7
Compare
sorry for causing extra review -- pushed and squashed indention fix. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK f5daff7
@@ -127,6 +127,9 @@ class CCheckQueue | |||
} | |||
|
|||
public: | |||
//! Mutex to ensure only one concurrent CCheckQueueControl | |||
boost::mutex ControlMutex; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Is there some coding standard for mutexes which makes you capitalize this ivar? If not, maybe controlMutex
would be more consistent.
#9497 was merged, which included this. Closing. |
There's a small race condition in the CCheckQueue code which I don't think is currently an active issue, but future code might break.
IsIdle is not threadsafe. If two concurrent
CCheckqueueControl
s are made, they could simultaneously report being idle, and fail to panic.Furthermore, in the case a concurrent
CCheckqueueControl
is made, most likely waiting until control is relinquished is the right behavior rather than failing an assert.