Skip to content

Commit

Permalink
Fixed a deadlock when tasks are scheduled while the worker threads ha…
Browse files Browse the repository at this point in the history
…ven't reached m_signal_work.wait() yet

Fixes #44
  • Loading branch information
ata4 committed Dec 25, 2017
1 parent cb39539 commit d52d94f
Showing 1 changed file with 12 additions and 7 deletions.
19 changes: 12 additions & 7 deletions core/parallel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,24 @@ class Parallel
{
public:
Parallel(uint32_t num_workers) {
std::unique_lock<std::mutex> ul(m_mutex);

// create worker threads
for (uint32_t worker_id = 0; worker_id < num_workers; worker_id++) {
m_workers.emplace_back(std::thread(&Parallel::do_work, this, worker_id));
}

// give workers an empty task and wait for them to finish it to
// make sure they're ready
m_task = [](uint32_t){};
m_workers_active = m_workers.size();
m_signal_done.wait(ul);
}

~Parallel() {
// wait for all workers to finish their current work
wait();

// set a dummy task in case nothing has been done yet
if (!m_task) {
m_task = [](uint32_t) {};
}

// exit worker main loops
m_accept_work = false;
m_signal_work.notify_all();
Expand Down Expand Up @@ -66,12 +69,14 @@ class Parallel
void do_work(int32_t worker_id) {
std::unique_lock<std::mutex> ul(m_mutex);
while (m_accept_work) {
m_signal_work.wait(ul);
ul.unlock();
m_task(worker_id);
if (m_accept_work) {
m_task(worker_id);
}
ul.lock();
m_workers_active--;
m_signal_done.notify_all();
m_signal_work.wait(ul);
}
}

Expand Down

0 comments on commit d52d94f

Please sign in to comment.