summaryrefslogtreecommitdiff
path: root/src/buildtool/multithreading/notification_queue.hpp
diff options
context:
space:
mode:
authorOliver Reiche <oliver.reiche@huawei.com>2022-07-05 17:05:13 +0200
committerOliver Reiche <oliver.reiche@huawei.com>2022-07-07 12:55:13 +0200
commitfa4bb79fa3e972efc0e59abfda89b3e57b472dfa (patch)
tree973b0551911bd523020ef623f283271959dd0123 /src/buildtool/multithreading/notification_queue.hpp
parent1af5a281460901281104532c9bb398adcf269eb9 (diff)
downloadjustbuild-fa4bb79fa3e972efc0e59abfda89b3e57b472dfa.tar.gz
TaskSystem: Implement shutdown
Diffstat (limited to 'src/buildtool/multithreading/notification_queue.hpp')
-rw-r--r--src/buildtool/multithreading/notification_queue.hpp26
1 files changed, 20 insertions, 6 deletions
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 <deque>
#include <mutex>
#include <optional>
+#include <shared_mutex>
#include <utility> // 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<std::size_t> count_{};
+ std::shared_mutex mutex_{};
+ std::condition_variable_any cv_{};
+ std::atomic<std::size_t> count_{};
+ std::atomic<bool> done_{};
+
+ [[nodiscard]] auto IsZero() noexcept -> bool {
+ return count_ == 0 or done_;
+ }
};
class NotificationQueue {