Fix CCheckQueue IsIdle (potential) race condition and remove dangerous constructors.

This commit is contained in:
Jeremy Rubin 2017-01-09 11:13:37 -05:00
parent 25720fc394
commit e2073424fd

View file

@ -127,6 +127,9 @@ private:
} }
public: public:
//! Mutex to ensure only one concurrent CCheckQueueControl
boost::mutex ControlMutex;
//! Create a new check queue //! Create a new check queue
CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {} 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<boost::mutex> lock(mutex);
return (nTotal == nIdle && nTodo == 0 && fAllOk == true);
}
}; };
/** /**
@ -177,16 +174,18 @@ template <typename T>
class CCheckQueueControl class CCheckQueueControl
{ {
private: private:
CCheckQueue<T>* pqueue; CCheckQueue<T> * const pqueue;
bool fDone; bool fDone;
public: public:
CCheckQueueControl(CCheckQueue<T>* pqueueIn) : pqueue(pqueueIn), fDone(false) CCheckQueueControl() = delete;
CCheckQueueControl(const CCheckQueueControl&) = delete;
CCheckQueueControl& operator=(const CCheckQueueControl&) = delete;
explicit CCheckQueueControl(CCheckQueue<T> * const pqueueIn) : pqueue(pqueueIn), fDone(false)
{ {
// passed queue is supposed to be unused, or NULL // passed queue is supposed to be unused, or NULL
if (pqueue != NULL) { if (pqueue != NULL) {
bool isIdle = pqueue->IsIdle(); ENTER_CRITICAL_SECTION(pqueue->ControlMutex);
assert(isIdle);
} }
} }
@ -209,6 +208,9 @@ public:
{ {
if (!fDone) if (!fDone)
Wait(); Wait();
if (pqueue != NULL) {
LEAVE_CRITICAL_SECTION(pqueue->ControlMutex);
}
} }
}; };