diff options
author | Morph <39850852+Morph1984@users.noreply.github.com> | 2023-01-25 16:03:32 -0500 |
---|---|---|
committer | Morph <39850852+Morph1984@users.noreply.github.com> | 2023-01-25 16:43:04 -0500 |
commit | 9b0563fa878c6afa73e00a967bc24259ec72ef35 (patch) | |
tree | bdc9417d26426d876bfab679216ffb2e1c821080 /src | |
parent | b82a09896815c6c7c1c6f33673256860c16d0f9f (diff) |
polyfill_thread: Implement StoppableTimedWait
StoppableTimedWait allows for a timed wait to be stopped immediately after a stop is requested.
This is useful in cases where long duration thread sleeps are needed and allows for immediate joining of waiting threads after a stop is requested.
Co-Authored-By: liamwhite <liamwhite@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/common/polyfill_thread.h | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/common/polyfill_thread.h b/src/common/polyfill_thread.h index 5a8d1ce085..b2c929d2f1 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 |