25#ifndef __JOIN_TIMER_HPP__
26#define __JOIN_TIMER_HPP__
37#include <sys/timerfd.h>
48 template <
class ClockPolicy>
56 : _handle (timerfd_create (_policy.
type (), TFD_NONBLOCK))
79 : _callback (std::move (other._callback))
81 , _oneShot (other._oneShot)
82 , _handle (other._handle)
86 other._callback =
nullptr;
87 other._ns = std::chrono::nanoseconds::zero ();
88 other._oneShot =
true;
108 _callback = std::move (other._callback);
110 _oneShot = other._oneShot;
111 _handle = other._handle;
115 other._callback =
nullptr;
116 other._ns = std::chrono::nanoseconds::zero ();
117 other._oneShot =
true;
143 template <
class Rep,
class Period,
typename Func>
144 void setOneShot (std::chrono::duration <Rep, Period> duration, Func&& callback)
146 auto ns = std::chrono::duration_cast <std::chrono::nanoseconds> (duration);
147 _callback = std::forward <Func> (callback);
149 _ns = std::chrono::nanoseconds::zero ();
152 timerfd_settime (_handle, 0, &ts,
nullptr);
160 template <
class Clock,
class Duration,
typename Func>
161 void setOneShot (std::chrono::time_point <Clock, Duration> timePoint, Func&& callback)
164 (std::is_same <ClockPolicy, RealTime>::value && std::is_same <Clock, std::chrono::system_clock>::value) ||
165 (std::is_same <ClockPolicy, Monotonic>::value && std::is_same <Clock, std::chrono::steady_clock>::value),
166 "Clock type mismatch timer policy"
169 auto elapsed = timePoint.time_since_epoch ();
170 auto ns = std::chrono::duration_cast <std::chrono::nanoseconds> (elapsed);
171 _callback = std::forward <Func> (callback);
173 _ns = std::chrono::nanoseconds::zero ();
176 timerfd_settime (_handle, TFD_TIMER_ABSTIME, &ts,
nullptr);
184 template <
class Rep,
class Period,
typename Func>
185 void setInterval (std::chrono::duration <Rep, Period> duration, Func&& callback)
187 auto ns = std::chrono::duration_cast <std::chrono::nanoseconds> (duration);
188 _callback = std::forward <Func> (callback);
193 timerfd_settime (_handle, 0, &ts,
nullptr);
203 _ns = std::chrono::nanoseconds::zero ();
205 struct itimerspec ts {};
206 timerfd_settime (_handle, 0, &ts,
nullptr);
215 struct itimerspec ts {};
216 timerfd_gettime (_handle, &ts);
217 const bool hasValue = (ts.it_value.tv_sec != 0 || ts.it_value.tv_nsec != 0);
218 const bool hasInterval = (ts.it_interval.tv_sec != 0 || ts.it_interval.tv_nsec != 0);
219 return hasValue || hasInterval;
228 struct itimerspec ts {};
229 timerfd_gettime (_handle, &ts);
230 return std::chrono::seconds (ts.it_value.tv_sec) + std::chrono::nanoseconds (ts.it_value.tv_nsec);
237 std::chrono::nanoseconds
interval () const noexcept
257 return _policy.type ();
266 uint64_t expirations;
267 ssize_t result = read (_handle, &expirations,
sizeof (expirations));
268 if (result ==
sizeof (expirations) && _callback)
270 for (uint64_t i = 0; i < expirations; ++i)
283 static itimerspec
toTimerSpec (std::chrono::nanoseconds ns,
bool periodic =
false) noexcept
286 ts.it_value.tv_sec = ns.count () / NS_PER_SEC;
287 ts.it_value.tv_nsec = ns.count () % NS_PER_SEC;
290 ts.it_interval.tv_sec = ts.it_value.tv_sec;
291 ts.it_interval.tv_nsec = ts.it_value.tv_nsec;
300 virtual int handle () const noexcept
override
307 static constexpr uint64_t NS_PER_SEC = 1000000000ULL;
313 std::function <void ()> _callback;
316 std::chrono::nanoseconds _ns {};
319 bool _oneShot =
true;
331 using Timer = BasicTimer <RealTime>;
342 constexpr
int type () const noexcept
344 return CLOCK_REALTIME;
354 using Timer = BasicTimer <Monotonic>;
365 constexpr
int type () const noexcept
367 return CLOCK_MONOTONIC;
base timer class.
Definition timer.hpp:50
virtual int handle() const noexcept override
get native handle.
Definition timer.hpp:300
std::chrono::nanoseconds interval() const noexcept
get the interval of the running periodic timer.
Definition timer.hpp:237
void setOneShot(std::chrono::duration< Rep, Period > duration, Func &&callback)
arm the timer as a one-shot timer.
Definition timer.hpp:144
virtual ~BasicTimer()
destroy instance.
Definition timer.hpp:128
std::chrono::nanoseconds remaining() const
get the remaining time until expiration.
Definition timer.hpp:226
bool active() const
check if timer is running.
Definition timer.hpp:213
static itimerspec toTimerSpec(std::chrono::nanoseconds ns, bool periodic=false) noexcept
convert nsec to itimerspec.
Definition timer.hpp:283
BasicTimer(const BasicTimer &other)=delete
copy constructor.
BasicTimer()
create instance.
Definition timer.hpp:55
void cancel()
cancel the timer.
Definition timer.hpp:199
void setInterval(std::chrono::duration< Rep, Period > duration, Func &&callback)
arm the timer as a periodic timer.
Definition timer.hpp:185
BasicTimer(BasicTimer &&other) noexcept
move constructor.
Definition timer.hpp:78
void setOneShot(std::chrono::time_point< Clock, Duration > timePoint, Func &&callback)
arm the timer as a one-shot timer with absolute time.
Definition timer.hpp:161
bool oneShot() const noexcept
check if timer is a one-shot timer.
Definition timer.hpp:246
virtual void onReceive() override
method called when data are ready to be read on handle.
Definition timer.hpp:264
int type() const noexcept
get the timer type.
Definition timer.hpp:255
BasicTimer & operator=(const BasicTimer &other)=delete
copy assignment operator.
Event handler interface class.
Definition reactor.hpp:44
monotonic clock policy class.
Definition timer.hpp:352
constexpr Monotonic() noexcept=default
construct the timer policy instance by default.
constexpr int type() const noexcept
get timer type.
Definition timer.hpp:365
int delHandler(EventHandler *handler)
delete handler from reactor.
Definition reactor.cpp:120
int addHandler(EventHandler *handler)
add handler to reactor.
Definition reactor.cpp:77
static Reactor * instance()
create the Reactor instance.
Definition reactor.cpp:158
real time clock policy class.
Definition timer.hpp:329
constexpr int type() const noexcept
get timer type.
Definition timer.hpp:342
constexpr RealTime() noexcept=default
construct the timer policy instance by default.
Definition acceptor.hpp:32