1 | #pragma once |
---|---|
2 | |
3 | #include <cstdint> |
4 | #include <mutex> |
5 | #include <condition_variable> |
6 | |
7 | |
8 | /** Allow to subscribe for multiple events and wait for them one by one in arbitrary order. |
9 | */ |
10 | class EventCounter |
11 | { |
12 | private: |
13 | size_t events_happened = 0; |
14 | size_t events_waited = 0; |
15 | |
16 | mutable std::mutex mutex; |
17 | std::condition_variable condvar; |
18 | |
19 | public: |
20 | void notify() |
21 | { |
22 | { |
23 | std::lock_guard lock(mutex); |
24 | ++events_happened; |
25 | } |
26 | condvar.notify_all(); |
27 | } |
28 | |
29 | void wait() |
30 | { |
31 | std::unique_lock lock(mutex); |
32 | condvar.wait(lock, [&]{ return events_happened > events_waited; }); |
33 | ++events_waited; |
34 | } |
35 | |
36 | template <typename Duration> |
37 | bool waitFor(Duration && duration) |
38 | { |
39 | std::unique_lock lock(mutex); |
40 | if (condvar.wait(lock, std::forward<Duration>(duration), [&]{ return events_happened > events_waited; })) |
41 | { |
42 | ++events_waited; |
43 | return true; |
44 | } |
45 | return false; |
46 | } |
47 | }; |
48 |