hmbdc
simplify-high-performance-messaging-programming
Timers.hpp
1 #include "hmbdc/Copyright.hpp"
2 #pragma once
3 
4 #include "hmbdc/time/Time.hpp"
5 #include "hmbdc/Exception.hpp"
6 #include "hmbdc/Compile.hpp"
7 
8 #include <functional>
9 
10 #include <stdexcept>
11 #include <ctime>
12 
13 #include <boost/intrusive/set.hpp>
14 
15 
16 namespace hmbdc { namespace time {
17 
18 using namespace hmbdc;
19 using namespace hmbdc::time;
20 
21 struct TimerManager;
22 namespace detail {
23  void noop(TimerManager&, SysTime const&);
24 }
25 
26 struct Timer
27 : boost::intrusive::set_base_hook<
28  boost::intrusive::link_mode<boost::intrusive::normal_link>
29  //the default safe_link appears too strict since many times the object is deleted
30  //before the container(TimerManager) is deleted and assert fires unnecesarily in that case
31 > {
32 protected:
33  SysTime getFireAt() const { return fireAt_; }
34 
35 public:
36  using Callback = std::function<void (TimerManager&, SysTime const&)>;
37  Timer(Callback cb = detail::noop)
38  : armed(false)
39  , callback_(cb)
40  {}
41  void setCallback(Callback cb) {
42  callback_ = cb;
43  }
44  friend class TimerManager;
45  bool operator < (Timer const& other) const
46  { return fireAt_ < other.fireAt_; }
47  bool operator <= (SysTime const& t) const
48  { return !(t < fireAt_); }
49 
50  virtual ~Timer(){}
51 
52 private:
53  void fired(TimerManager& tm, SysTime const& now) {
54  callback_(tm, now);
55  }
56  bool armed;
57  SysTime fireAt_;
58  Callback callback_;
59  virtual void reschedule(TimerManager& tm, SysTime const& now) = 0;
60 };
61 
62 namespace detail {
63 inline
64 void noop(TimerManager&, SysTime const&)
65 {}
66 
67 } //detail
68 
69 struct TimerManager {
70  void schedule(SysTime fireAt, Timer& timer) {
71  timer.fireAt_ = fireAt;
72  timers_.insert(timer);
73  timer.armed = true;
74  }
75  /**
76  * @brief cancel a timer previously scheduled with the TimerManager
77  * @details if not scheduled, no effect
78  *
79  * @param timer to be canceled
80  */
81  void cancel(Timer& timer) {
82  auto range = timers_.equal_range(timer);
83  for (auto it = range.first; it != range.second; ++it) {
84  if (&*it == &timer) {
85  timers_.erase(it);
86  timer.armed = false;
87  return;
88  }
89  }
90  }
91 
92  void checkTimers(time::SysTime);
93 
94 private:
95  using Timers = boost::intrusive::multiset<Timer>;
96  Timers timers_;
97 };
98 
99 
101  ReoccuringTimer(Duration const& interval, Callback callback = detail::noop)
102  : Timer(callback)
103  , interval(interval)
104  {}
105  const Duration interval;
106 private:
107  virtual void reschedule(TimerManager& tm, SysTime const& now)
108  { tm.schedule(now + interval, *this); };
109 };
110 
111 struct DailyTimer : Timer {
112  DailyTimer(Callback callback = detail::noop)
113  : Timer(callback)
114  {}
115 private:
116  virtual void reschedule(TimerManager& tm, SysTime const& now) {
117  Duration day = Duration::seconds(86400);
118  SysTime newFireTime = getFireAt() + day;
119  while (newFireTime < now) newFireTime += day;
120  tm.schedule(newFireTime, *this);
121  };
122 };
123 
124 struct OneTimeTimer : Timer {
125  OneTimeTimer(Callback callback = detail::noop)
126  : Timer(callback)
127  {}
128 
129 private:
130  virtual void reschedule(TimerManager&, SysTime const&){};
131 };
132 
133 }}
Definition: Timers.hpp:26
Definition: Timers.hpp:69
Definition: Timers.hpp:111
void cancel(Timer &timer)
cancel a timer previously scheduled with the TimerManager
Definition: Timers.hpp:81
Definition: Time.hpp:15
Definition: Timers.hpp:124
Definition: Time.hpp:118
Definition: Rater.hpp:10
Definition: Client.hpp:11
Definition: Timers.hpp:100