This member function does not affect the logical state of the class.
Making std::condition_variable and std::mutex data members mutable is
idiomatic as these classes are thread-safe synchronization primitives.
ConcurrentQueue is currently used only by two classes and a test, but
modifying concurrent_queue.h requires recompiling 30 source files. None
of the member functions is so lightweight as to make it worth inlining.
An alternative to `@note ConcurrentQueue is unable to execute jobs if
@p threadCount == 0.` is `assert(threadCount != 0);`. But this would
force classes that contain a ConcurrentQueue data member to always start
a thread, even if they detect at runtime that they are never going to
enqueue a job.
Add Job type alias to avoid repeating the type.
Use default member initializers instead of the member initializer list
to make it clear [to the reader of the header] that no data member is
left uninitialized.
Add another data column to randomCalls() - boostEnqueueOperationWeight -
that determines whether or not enqueue() operation's weight/probability
is much greater than the other operations' weights. The new column
allows to retain the existing much-closer-to-equal weights, which test
other aspects of ConcurrentQueue and have detected bugs already.
Reduce the number of thread count data rows to offset the test duration
increase somewhat.
The new test is a randomized stress test. It consistently passes right
now. The test's detailed output can be analyzed to reveal anomalies and
bugs. The test can catch various bugs that future changes to
ConcurrentQueue's code may introduce.
ConcurrentQueueTest::cancelPending1UserThread() often fails when
ConcurrentQueueTest is launched from Qt Creator immediately after
switching between Debug and Release YACReader build configurations.
The CPU busyness must be affecting the thread scheduling timing, which
breaks the test's timing assumptions in this case.
Use the return value of ConcurrentQueue::cancelPending() instead of
relying on the timing of thread scheduling to determine the number of
canceled jobs.
Place common Qt Test qmake code into tests/qt_test.pri.
Build tests as part of top-level YACReader project unless no_tests
CONFIG option is set. This way the tests are built by default during
development. Packagers can skip building tests by running
`qmake "CONFIG+=no_tests"`.
Both ConcurrentQueueTest::singleUserThread() and
ConcurrentQueueTest::multipleUserThreads() pass. Evidently
ConcurrentQueue::enqueue() can be safely called from multiple threads on
the same ConcurrentQueue object with no additional synchronization. Once
each thread enqueues all its jobs, one thread can safely call waitAll().