Skip to content

Commit

Permalink
Port Core #9497: CCheckQueue Unit Tests
Browse files Browse the repository at this point in the history
96c7f2c Add CheckQueue Tests (Jeremy Rubin)
e207342 Fix CCheckQueue IsIdle (potential) race condition and remove dangerous constructors. (Jeremy Rubin)
  • Loading branch information
laanwj authored and sickpig committed Apr 10, 2018
1 parent 35ceb25 commit e1e28f4
Show file tree
Hide file tree
Showing 3 changed files with 456 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ BITCOIN_TESTS =\
test/bswap_tests.cpp \
test/cashaddr_tests.cpp \
test/cashaddrenc_tests.cpp \
test/checkqueue_tests.cpp \
test/coins_tests.cpp \
test/compress_tests.cpp \
test/crypto_tests.cpp \
Expand Down
34 changes: 13 additions & 21 deletions src/checkqueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ class CCheckQueue
}

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)
Expand Down Expand Up @@ -176,11 +179,6 @@ class CCheckQueue
}

~CCheckQueue() {}
bool IsIdle()
{
boost::unique_lock<boost::mutex> lock(mutex);
return (nTotal == nIdle && nTodo == 0 && fAllOk == true);
}
};

/**
Expand All @@ -191,30 +189,20 @@ template <typename T>
class CCheckQueueControl
{
private:
CCheckQueue<T> *pqueue;
CCheckQueue<T> *const pqueue;
bool fDone;

public:
CCheckQueueControl() {} // BU: parallel block validation
CCheckQueueControl(CCheckQueue<T> *pqueueIn) : pqueue(pqueueIn), fDone(false)
{
// passed queue is supposed to be unused, or NULL
if (pqueue != NULL)
{
bool isIdle = pqueue->IsIdle();
assert(isIdle);
}
}

void Queue(CCheckQueue<T> *pqueueIn)
CCheckQueueControl() = delete;
CCheckQueueControl(const CCheckQueueControl &) = delete;
CCheckQueueControl &operator=(const CCheckQueueControl &) = delete;
explicit CCheckQueueControl(CCheckQueue<T> *const pqueueIn) : pqueue(pqueueIn), fDone(false)
{
pqueue = pqueueIn;
// passed queue is supposed to be unused, or NULL
if (pqueue != NULL)
{
bool isIdle = pqueue->IsIdle();
assert(isIdle);
fDone = false;
ENTER_CRITICAL_SECTION(pqueue->ControlMutex);
}
}

Expand All @@ -239,6 +227,10 @@ class CCheckQueueControl
{
if (!fDone)
Wait();
if (pqueue != NULL)
{
LEAVE_CRITICAL_SECTION(pqueue->ControlMutex);
}
}
};

Expand Down
Loading

0 comments on commit e1e28f4

Please sign in to comment.