client-cpp  0.8.1
KaaTimer.hpp
Go to the documentation of this file.
1 
17 #ifndef KAATIMER_HPP_
18 #define KAATIMER_HPP_
19 
20 #include <chrono>
21 #include <mutex>
22 #include <thread>
23 #include <functional>
24 #include <condition_variable>
25 
26 #include "kaa/KaaThread.hpp"
27 #include "kaa/logging/Log.hpp"
29 
30 namespace kaa {
31 
32 template<class Signature, class Function = std::function<Signature>>
33 class KaaTimer {
34  typedef std::chrono::system_clock TimerClock;
35 public:
36  KaaTimer(const std::string& timerName) :
37  timerName_(timerName), isThreadRun_(false), isTimerRun_(false), callback_([]{})
38  {
39  }
40 
42  {
43  /*
44  * Do not add the mutex logging it may cause crashes.
45  */
46  if (isThreadRun_ && timerThread_.joinable()) {
47  std::unique_lock<std::mutex> timerLock(timerGuard_);
48 
49  isThreadRun_ = false;
50  condition_.notify_one();
51 
52  timerLock.unlock();
53 
54  timerThread_.join();
55  }
56  }
57 
58  void start(std::size_t seconds, const Function& callback)
59  {
60  if (!callback) {
61  throw KaaException("Bad timer callback");
62  }
63  std::unique_lock<std::mutex> timerLock(timerGuard_);
64 
65  if (!isThreadRun_) {
66  isThreadRun_ = true;
67  timerThread_ = std::thread([&] { run(); });
68  }
69 
70  if (!isTimerRun_) {
71  endTS_ = TimerClock::now() + std::chrono::seconds(seconds);
72  isTimerRun_ = true;
73  callback_ = callback;
74  condition_.notify_one();
75  }
76  }
77 
78  void stop()
79  {
80  std::unique_lock<std::mutex> timerLock(timerGuard_);
81 
82  if (isTimerRun_) {
83  isTimerRun_ = false;
84  condition_.notify_one();
85  }
86  }
87 
88 private:
89  void run()
90  {
91  std::unique_lock<std::mutex> timerLock(timerGuard_);
92 
93  while (isThreadRun_) {
94  if (isTimerRun_) {
95  auto now = TimerClock::now();
96  if (now >= endTS_) {
97  isTimerRun_ = false;
98 
99  auto currentCallback = callback_;
100 
101  timerLock.unlock();
102 
103  currentCallback();
104 
105  timerLock.lock();
106  } else {
107  condition_.wait_for(timerLock, (endTS_ - now));
108  }
109  } else {
110  condition_.wait(timerLock);
111  }
112  }
113  }
114 
115 private:
116  const std::string timerName_;
117 
118  bool isThreadRun_;
119  bool isTimerRun_;
120 
121  std::thread timerThread_;
122  std::condition_variable condition_;
123 
124  std::mutex timerGuard_;
125 
126  std::chrono::time_point<TimerClock> endTS_;
127 
128  Function callback_;
129 };
130 
131 } /* namespace kaa */
132 
133 #endif /* KAATIMER_HPP_ */
KaaTimer(const std::string &timerName)
Definition: KaaTimer.hpp:36
void start(std::size_t seconds, const Function &callback)
Definition: KaaTimer.hpp:58
void stop()
Definition: KaaTimer.hpp:78