X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=quittable_sleeper.h;fp=quittable_sleeper.h;h=ba00e73b1184e9d388c04867b080773247547820;hb=f07adb19f0e2571bf4894ec57e6fcfe4a3e5fd95;hp=0000000000000000000000000000000000000000;hpb=b6089b76678e76271616131672c5ba454a5d336d;p=nageru diff --git a/quittable_sleeper.h b/quittable_sleeper.h new file mode 100644 index 0000000..ba00e73 --- /dev/null +++ b/quittable_sleeper.h @@ -0,0 +1,59 @@ +#ifndef _QUITTABLE_SLEEPER +#define _QUITTABLE_SLEEPER 1 + +// A class that assists with fast shutdown of threads. You can set +// a flag that says the thread should quit, which it can then check +// in a loop -- and if the thread sleeps (using the sleep_* functions +// on the class), that sleep will immediately be aborted. +// +// All member functions on this class are thread-safe. + +#include +#include + +class QuittableSleeper { +public: + void quit() + { + std::lock_guard l(mu); + should_quit_var = true; + quit_cond.notify_all(); + } + + void unquit() + { + std::lock_guard l(mu); + should_quit_var = false; + } + + bool should_quit() const + { + std::lock_guard l(mu); + return should_quit_var; + } + + template + void sleep_for(const std::chrono::duration &duration) + { + std::chrono::steady_clock::time_point t = + std::chrono::steady_clock::now() + + std::chrono::duration_cast(duration); + sleep_until(t); + } + + template + void sleep_until(const std::chrono::time_point &t) + { + std::unique_lock lock(mu); + quit_cond.wait_until(lock, t, [this]{ + return should_quit_var; + }); + } + +private: + mutable std::mutex mu; + bool should_quit_var = false; + std::condition_variable quit_cond; +}; + +#endif // !defined(_QUITTABLE_SLEEPER)