From fa4bb79fa3e972efc0e59abfda89b3e57b472dfa Mon Sep 17 00:00:00 2001 From: Oliver Reiche Date: Tue, 5 Jul 2022 17:05:13 +0200 Subject: TaskSystem: Implement shutdown --- .../multithreading/notification_queue.hpp | 26 +++++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'src/buildtool/multithreading/notification_queue.hpp') diff --git a/src/buildtool/multithreading/notification_queue.hpp b/src/buildtool/multithreading/notification_queue.hpp index 5965fde0..dd766722 100644 --- a/src/buildtool/multithreading/notification_queue.hpp +++ b/src/buildtool/multithreading/notification_queue.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include // std::forward #include "gsl-lite/gsl-lite.hpp" @@ -17,23 +18,36 @@ class WaitableZeroCounter { explicit WaitableZeroCounter(std::size_t init = 0) : count_{init} {} void Decrement() { + std::shared_lock lock{mutex_}; if (--count_ == 0) { - count_.notify_all(); + cv_.notify_all(); } } void Increment() { ++count_; } void WaitForZero() { - auto val = count_.load(); - while (val != 0) { // loop to protect against spurious wakeups - count_.wait(val); - val = count_.load(); + while (not IsZero()) { // loop to protect against spurious wakeups + std::unique_lock lock{mutex_}; + cv_.wait(lock, [this] { return IsZero(); }); } } + void Abort() { + std::shared_lock lock{mutex_}; + done_ = true; + cv_.notify_all(); + } + private: - atomic count_{}; + std::shared_mutex mutex_{}; + std::condition_variable_any cv_{}; + std::atomic count_{}; + std::atomic done_{}; + + [[nodiscard]] auto IsZero() noexcept -> bool { + return count_ == 0 or done_; + } }; class NotificationQueue { -- cgit v1.2.3