summaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/polyfill_thread.h36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/common/polyfill_thread.h b/src/common/polyfill_thread.h
index 5a8d1ce08..b2c929d2f 100644
--- a/src/common/polyfill_thread.h
+++ b/src/common/polyfill_thread.h
@@ -11,6 +11,8 @@
#ifdef __cpp_lib_jthread
+#include <chrono>
+#include <condition_variable>
#include <stop_token>
#include <thread>
@@ -21,11 +23,23 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred&& pred) {
cv.wait(lock, token, std::move(pred));
}
+template <typename Rep, typename Period>
+bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
+ std::condition_variable_any cv;
+ std::mutex m;
+
+ // Perform the timed wait.
+ std::unique_lock lk{m};
+ return !cv.wait_for(lk, token, rel_time, [&] { return token.stop_requested(); });
+}
+
} // namespace Common
#else
#include <atomic>
+#include <chrono>
+#include <condition_variable>
#include <functional>
#include <list>
#include <memory>
@@ -318,6 +332,28 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred pred) {
cv.wait(lock, [&] { return pred() || token.stop_requested(); });
}
+template <typename Rep, typename Period>
+bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
+ if (token.stop_requested()) {
+ return false;
+ }
+
+ bool stop_requested = false;
+ std::condition_variable cv;
+ std::mutex m;
+
+ std::stop_callback cb(token, [&] {
+ // Wake up the waiting thread.
+ std::unique_lock lk{m};
+ stop_requested = true;
+ cv.notify_one();
+ });
+
+ // Perform the timed wait.
+ std::unique_lock lk{m};
+ return !cv.wait_for(lk, rel_time, [&] { return stop_requested; });
+}
+
} // namespace Common
#endif