From e2073424fd5a185781750347fbfbb0c108ef66fd Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Mon, 9 Jan 2017 11:13:37 -0500 Subject: [PATCH] Fix CCheckQueue IsIdle (potential) race condition and remove dangerous constructors. --- src/checkqueue.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/checkqueue.h b/src/checkqueue.h index 32e25d5c8..ea12df66d 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -127,6 +127,9 @@ private: } public: + //! Mutex to ensure only one concurrent CCheckQueueControl + boost::mutex ControlMutex; + //! Create a new check queue CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {} @@ -161,12 +164,6 @@ public: { } - bool IsIdle() - { - boost::unique_lock lock(mutex); - return (nTotal == nIdle && nTodo == 0 && fAllOk == true); - } - }; /** @@ -177,16 +174,18 @@ template class CCheckQueueControl { private: - CCheckQueue* pqueue; + CCheckQueue * const pqueue; bool fDone; public: - CCheckQueueControl(CCheckQueue* pqueueIn) : pqueue(pqueueIn), fDone(false) + CCheckQueueControl() = delete; + CCheckQueueControl(const CCheckQueueControl&) = delete; + CCheckQueueControl& operator=(const CCheckQueueControl&) = delete; + explicit CCheckQueueControl(CCheckQueue * const pqueueIn) : pqueue(pqueueIn), fDone(false) { // passed queue is supposed to be unused, or NULL if (pqueue != NULL) { - bool isIdle = pqueue->IsIdle(); - assert(isIdle); + ENTER_CRITICAL_SECTION(pqueue->ControlMutex); } } @@ -209,6 +208,9 @@ public: { if (!fDone) Wait(); + if (pqueue != NULL) { + LEAVE_CRITICAL_SECTION(pqueue->ControlMutex); + } } };