1 // Copyright (c) 2016-2022 The Limenka developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 5 #ifndef LIMENKA_UTIL_THREADINTERRUPT_H
6 #define LIMENKA_UTIL_THREADINTERRUPT_H
7 8 #include <sync.h>
9 #include <threadsafety.h>
10 11 #include <atomic>
12 #include <chrono>
13 #include <condition_variable>
14 15 /**
16 * A helper class for interruptible sleeps. Calling operator() will interrupt
17 * any current sleep, and after that point operator bool() will return true
18 * until reset.
19 *
20 * This class should not be used in a signal handler. It uses thread
21 * synchronization primitives that are not safe to use with signals. If sending
22 * an interrupt from a signal handler is necessary, the \ref SignalInterrupt
23 * class can be used instead.
24 */
25 26 class CThreadInterrupt
27 {
28 public:
29 using Clock = std::chrono::steady_clock;
30 CThreadInterrupt();
31 explicit operator bool() const;
32 void operator()() EXCLUSIVE_LOCKS_REQUIRED(!mut);
33 void reset();
34 bool sleep_for(Clock::duration rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut);
35 36 private:
37 std::condition_variable cond;
38 Mutex mut;
39 std::atomic<bool> flag;
40 };
41 42 #endif // LIMENKA_UTIL_THREADINTERRUPT_H
43