5#include <condition_variable>
22 Semaphore(
unsigned int count = 0) : m_count(count)
31 template <
class Clock,
class Duration>
32 bool waitUntil(
const std::chrono::time_point<Clock, Duration>& point)
34 std::unique_lock<std::mutex> lock(m_mtx);
35 if(!m_cv.wait_until(lock, point, [
this]() {
return m_count > 0 || m_unlock; }))
59 std::condition_variable m_cv;
60 std::atomic_uint m_count = 0;
61 std::atomic_bool m_unlock =
false;
75template <
typename ClockT = std::chrono::steady_clock,
76 typename DurationT = std::chrono::steady_clock::duration>
82 m_finish.store(
false);
83 m_thread = std::thread([
this]() { run(); });
93 if(m_thread.joinable())
103 uint64_t
add(std::chrono::milliseconds milliseconds, std::function<
void(
bool)> handler)
106 item.end = ClockT::now() + milliseconds;
107 item.handler = std::move(handler);
109 std::unique_lock<std::mutex> lk(m_mtx);
110 uint64_t id = ++m_idcounter;
112 m_items.push(std::move(item));
116 m_checkWork.notify();
132 std::unique_lock<std::mutex> lk(m_mtx);
133 for(
auto&& item : m_items.getContainer())
135 if(item.id == id && item.handler)
139 newItem.end = std::chrono::time_point<ClockT, DurationT>();
146 newItem.handler = std::move(item.handler);
147 item.handler =
nullptr;
148 m_items.push(std::move(newItem));
152 m_checkWork.notify();
166 std::unique_lock<std::mutex> lk(m_mtx);
167 for(
auto&& item : m_items.getContainer())
171 item.end = std::chrono::time_point<ClockT, DurationT>();
175 auto ret = m_items.size();
178 m_checkWork.notify();
190 while(!m_finish.load())
192 auto end = calcWaitTime();
197 m_checkWork.waitUntil(end.second);
202 m_checkWork.waitUntil(ClockT::now() + std::chrono::milliseconds(10));
216 assert(m_items.size() == 0);
219 std::pair<
bool, std::chrono::time_point<ClockT, DurationT>> calcWaitTime()
221 std::lock_guard<std::mutex> lk(m_mtx);
222 while(m_items.size())
224 if(m_items.top().handler)
227 return std::make_pair(
true, m_items.top().end);
238 return std::make_pair(
false, std::chrono::time_point<ClockT, DurationT>());
243 std::unique_lock<std::mutex> lk(m_mtx);
244 while(m_items.size() && m_items.top().end <= ClockT::now())
246 WorkItem item(std::move(m_items.top()));
252 item.handler(item.id == 0);
259 std::thread m_thread;
260 std::atomic_bool m_finish =
false;
261 uint64_t m_idcounter = 0;
265 std::chrono::time_point<ClockT, DurationT> end;
267 std::function<
void(
bool)> handler;
268 bool operator>(
const WorkItem& other)
const
270 return end > other.end;
277 :
public std::priority_queue<WorkItem, std::vector<WorkItem>, std::greater<WorkItem>>
280 std::vector<WorkItem>& getContainer()
Definition: timer_queue.h:78
size_t cancelAll()
Cancels all timers.
Definition: timer_queue.h:162
size_t cancel(uint64_t id)
Cancels the specified timer.
Definition: timer_queue.h:125
uint64_t add(std::chrono::milliseconds milliseconds, std::function< void(bool)> handler)
Adds a new timer.
Definition: timer_queue.h:103
Definition: timer_queue.h:20
The SwitchNode is equivalent to a switch statement, where a certain branch (child) is executed accord...
Definition: basic_types.h:540
Definition: action_node.h:24