From 0639ffcfb52c86722fc718fc854ce0818711fc34 Mon Sep 17 00:00:00 2001 From: Silent Date: Sat, 10 Aug 2019 19:38:22 +0200 Subject: [PATCH] Handle spurious wakeups on worker thread condition variables properly --- ext/native/thread/threadpool.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ext/native/thread/threadpool.cpp b/ext/native/thread/threadpool.cpp index f821fc121d..cdb3db217a 100644 --- a/ext/native/thread/threadpool.cpp +++ b/ext/native/thread/threadpool.cpp @@ -27,7 +27,7 @@ void WorkerThread::Process(std::function work) { void WorkerThread::WaitForCompletion() { std::unique_lock guard(doneMutex); - if (jobsDone < jobsTarget) { + while (jobsDone < jobsTarget) { done.wait(guard); } } @@ -37,7 +37,11 @@ void WorkerThread::WorkFunc() { std::unique_lock guard(mutex); started = true; while (active) { - signal.wait(guard); + // 'active == false' is one of the conditions for signaling, + // do not "optimize" it + while (active && jobsTarget <= jobsDone) { + signal.wait(guard); + } if (active) { work_(); doneMutex.lock(); @@ -67,7 +71,11 @@ void LoopWorkerThread::WorkFunc() { std::unique_lock guard(mutex); started = true; while (active) { - signal.wait(guard); + // 'active == false' is one of the conditions for signaling, + // do not "optimize" it + while (active && jobsTarget <= jobsDone) { + signal.wait(guard); + } if (active) { work_(start_, end_); doneMutex.lock();