Let me start by saying that this is a nicely written class with good documentation. I also think that Nobody's answer Nobody's answer provides some good advice, so mostly I'll build on that.
Let me start by saying that this is a nicely written class with good documentation. I also think that Nobody's answer provides some good advice, so mostly I'll build on that.
Let me start by saying that this is a nicely written class with good documentation. I also think that Nobody's answer provides some good advice, so mostly I'll build on that.
(This is only a partial solution; you'll have to add a condition variable or similar to make sure that future calls to joinAll
don't return before this one joins all its threads).
You document WorkQueue::WorkQueue
, saying that numWorkers < 0
causes autodetection, but you autodetect whenever numWorkers < 1
. That is, your documentation and implementation differ on behavior when numWorkers == 0
.
You document WorkQueue::WorkQueue
, saying that numWorkers < 0
causes autodetection, but you autodetect whenever numWorkers < 1
. That is, your documentation and implementation differ on behavior when numWorkers == 0
.
(This is only a partial solution; you'll have to add a condition variable or similar to make sure that future calls to joinAll
don't return before this one joins all its threads).
You document WorkQueue::WorkQueue
, saying that numWorkers < 0
causes autodetection, but you autodetect whenever numWorkers < 1
. That is, your documentation and implementation differ on behavior when numWorkers == 0
.
I only have one correctness comment: you have problematic behavior in joinAll
. If waitForCompletion
and/or abort
are called from multiple threads (and I can certainly imagine one thread calling waitForCompletion
and another thread later calling abort
), you have a race in joinAll
; one thread may be mid-iteration when the other calls m_workers.clear()
. Try the following:
void joinAll(){
std::vector<std::thread> workers;
{
std::lock_guard<std::mutex> lg(m_mutex);
workers = std::move(m_workers);
}
for (auto& thread : workers) {
thread.join();
}
}
I only have one correctness comment: you have problematic behavior in joinAll
. If waitForCompletion
and/or abort
are called from multiple threads (and I can certainly imagine one thread calling waitForCompletion
and another thread later calling abort
), you have a race in joinAll
; one thread may be mid-iteration when the other calls m_workers.clear()
.
I only have one correctness comment: you have problematic behavior in joinAll
. If waitForCompletion
and/or abort
are called from multiple threads (and I can certainly imagine one thread calling waitForCompletion
and another thread later calling abort
), you have a race in joinAll
; one thread may be mid-iteration when the other calls m_workers.clear()
. Try the following:
void joinAll(){
std::vector<std::thread> workers;
{
std::lock_guard<std::mutex> lg(m_mutex);
workers = std::move(m_workers);
}
for (auto& thread : workers) {
thread.join();
}
}