1 #ifndef _QUITTABLE_SLEEPER
2 #define _QUITTABLE_SLEEPER 1
4 // A class that assists with fast shutdown of threads. You can set
5 // a flag that says the thread should quit, which it can then check
6 // in a loop -- and if the thread sleeps (using the sleep_* functions
7 // on the class), that sleep will immediately be aborted.
9 // All member functions on this class are thread-safe.
12 #include <condition_variable>
15 class QuittableSleeper {
19 std::lock_guard<std::mutex> l(mu);
20 should_quit_var = true;
21 quit_cond.notify_all();
26 std::lock_guard<std::mutex> l(mu);
27 should_quit_var = false;
32 std::lock_guard<std::mutex> l(mu);
33 should_wakeup_var = true;
34 quit_cond.notify_all();
37 bool should_quit() const
39 std::lock_guard<std::mutex> l(mu);
40 return should_quit_var;
43 // Returns false if woken up early.
44 template<class Rep, class Period>
45 bool sleep_for(const std::chrono::duration<Rep, Period> &duration)
47 std::chrono::steady_clock::time_point t =
48 std::chrono::steady_clock::now() +
49 std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration);
50 return sleep_until(t);
53 // Returns false if woken up early.
54 template<class Clock, class Duration>
55 bool sleep_until(const std::chrono::time_point<Clock, Duration> &t)
57 std::unique_lock<std::mutex> lock(mu);
58 quit_cond.wait_until(lock, t, [this]{
59 return should_quit_var || should_wakeup_var;
61 if (should_wakeup_var) {
62 should_wakeup_var = false;
65 return !should_quit_var;
69 mutable std::mutex mu;
70 bool should_quit_var = false, should_wakeup_var = false;
71 std::condition_variable quit_cond;
74 #endif // !defined(_QUITTABLE_SLEEPER)