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(); });
90 if(m_thread.joinable())
100 uint64_t
add(std::chrono::milliseconds milliseconds, std::function<
void(
bool)> handler)
103 item.end = ClockT::now() + milliseconds;
104 item.handler = std::move(handler);
106 std::unique_lock<std::mutex> lk(m_mtx);
107 uint64_t id = ++m_idcounter;
109 m_items.push(std::move(item));
113 m_checkWork.notify();
129 std::unique_lock<std::mutex> lk(m_mtx);
130 for(
auto&& item : m_items.getContainer())
132 if(item.id == id && item.handler)
136 newItem.end = std::chrono::time_point<ClockT, DurationT>();
143 newItem.handler = std::move(item.handler);
144 item.handler =
nullptr;
145 m_items.push(std::move(newItem));
149 m_checkWork.notify();
163 std::unique_lock<std::mutex> lk(m_mtx);
164 for(
auto&& item : m_items.getContainer())
168 item.end = std::chrono::time_point<ClockT, DurationT>();
172 auto ret = m_items.size();
175 m_checkWork.notify();
187 while(!m_finish.load())
189 auto end = calcWaitTime();
194 m_checkWork.waitUntil(end.second);
199 m_checkWork.waitUntil(ClockT::now() + std::chrono::milliseconds(10));
209 assert(m_items.size() == 0);
212 std::pair<
bool, std::chrono::time_point<ClockT, DurationT>> calcWaitTime()
214 std::lock_guard<std::mutex> lk(m_mtx);
215 while(m_items.size())
217 if(m_items.top().handler)
220 return std::make_pair(
true, m_items.top().end);
231 return std::make_pair(
false, std::chrono::time_point<ClockT, DurationT>());
236 std::unique_lock<std::mutex> lk(m_mtx);
237 while(m_items.size() && m_items.top().end <= ClockT::now())
239 WorkItem item(std::move(m_items.top()));
245 item.handler(item.id == 0);
252 std::thread m_thread;
253 std::atomic_bool m_finish =
false;
254 uint64_t m_idcounter = 0;
258 std::chrono::time_point<ClockT, DurationT> end;
260 std::function<
void(
bool)> handler;
261 bool operator>(
const WorkItem& other)
const
263 return end > other.end;
270 :
public std::priority_queue<WorkItem, std::vector<WorkItem>, std::greater<WorkItem>>
273 std::vector<WorkItem>& getContainer()
Definition: timer_queue.h:78
size_t cancelAll()
Cancels all timers.
Definition: timer_queue.h:159
size_t cancel(uint64_t id)
Cancels the specified timer.
Definition: timer_queue.h:122
uint64_t add(std::chrono::milliseconds milliseconds, std::function< void(bool)> handler)
Adds a new timer.
Definition: timer_queue.h:100
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:515
Definition: action_node.h:24