Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
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); |
sipa
Jan 9, 2017
Owner
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)?
JeremyRubin
Jan 9, 2017
Contributor
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.
ryanofsky
approved these changes
Jan 11, 2017
utACK 958ee1d 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.
| - if (pqueue != NULL) { | ||
| - ENTER_CRITICAL_SECTION(pqueue->ControlMutex); | ||
| - } | ||
| + CCheckQueueControl<T>() = delete; |
|
Squashed and addressed @ryanofsky's nit about template args in constructors. |
| + CCheckQueueControl& operator=(const CCheckQueueControl&) = delete; | ||
| + explicit CCheckQueueControl(CCheckQueue<T> * const pqueueIn) : pqueue(pqueueIn), fDone(false) | ||
| + { | ||
| + // passed queue is supposed to be unused, or NULL |
|
sorry for causing extra review -- pushed and squashed indention fix. |
| @@ -127,6 +127,9 @@ class CCheckQueue | ||
| } | ||
| public: | ||
| + //! Mutex to ensure only one concurrent CCheckQueueControl | ||
| + boost::mutex ControlMutex; |
kallewoof
Feb 28, 2017
Member
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. |
JeremyRubin commentedJan 9, 2017
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
CCheckqueueControls are made, they could simultaneously report being idle, and fail to panic.Furthermore, in the case a concurrent
CCheckqueueControlis made, most likely waiting until control is relinquished is the right behavior rather than failing an assert.