Diag-Client-Lib
sync_timer.h
Go to the documentation of this file.
1 /* Diagnostic Client library
2 * Copyright (C) 2024 Avijit Dey
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 */
8 #ifndef DIAGNOSTIC_CLIENT_LIB_LIB_UTILITY_UTILITY_SYNC_TIMER_H
9 #define DIAGNOSTIC_CLIENT_LIB_LIB_UTILITY_UTILITY_SYNC_TIMER_H
10 
11 namespace utility {
12 namespace sync_timer {
13 
14 #include <chrono>
15 #include <condition_variable>
16 #include <mutex>
17 
23 template<typename ClockType>
24 class SyncTimer final {
25  public:
29  using Clock = ClockType;
30 
34  using TimePoint = std::chrono::time_point<Clock>;
35 
39  enum class TimerState : std::uint8_t { kIdle = 0, kCancelRequested, kTimeout };
40 
45 
50  std::lock_guard<std::mutex> const lck(mutex_lock_);
51  exit_request_ = false;
52  start_running_ = false;
53  cond_var_.notify_all();
54  }
55 
69  template<typename TimeoutCallback, typename CancelCallback>
70  void WaitForTimeout(TimeoutCallback &&timeout_func, CancelCallback &&cancellation_func,
71  std::chrono::milliseconds const timeout) {
72  if (Start(timeout) == TimerState::kTimeout) {
73  timeout_func();
74  } else {
75  cancellation_func();
76  }
77  }
78 
82  auto IsTimerActive() {
83  std::lock_guard<std::mutex> const lck(mutex_lock_);
84  return start_running_;
85  }
86 
90  void CancelWait() { Stop(); }
91 
92  private:
100  auto Start(std::chrono::milliseconds const timeout) noexcept -> TimerState {
101  TimerState timer_state{TimerState::kIdle};
102  std::unique_lock<std::mutex> lck(mutex_lock_);
103  start_running_ = true;
104  TimePoint const expiry_time_point{Clock::now() + timeout};
105  if (cond_var_.wait_until(lck, expiry_time_point, [this, &expiry_time_point, &timer_state]() {
106  bool do_exit_wait{false};
107  // check if exit was requested
108  if (!exit_request_) {
109  TimePoint const current_time{Clock::now()};
110  // check for expiry
111  if (current_time >= expiry_time_point) {
112  // timeout
113  timer_state = TimerState::kTimeout;
114  do_exit_wait = true;
115  } else {
116  // check for cancellation request
117  if (!start_running_) {
118  timer_state = TimerState::kCancelRequested;
119  do_exit_wait = true;
120  } // else - spurious wake-up, do nothing
121  }
122  } else {
123  do_exit_wait = true;
124  }
125  return do_exit_wait;
126  })) {}
127  return timer_state;
128  }
129 
133  void Stop() noexcept {
134  std::lock_guard<std::mutex> const lck(mutex_lock_);
135  start_running_ = false;
136  cond_var_.notify_all();
137  }
138 
139  private:
143  std::condition_variable cond_var_;
144 
148  std::mutex mutex_lock_;
149 
154 
159 };
160 
161 } // namespace sync_timer
162 } // namespace utility
163 
164 #endif // DIAGNOSTIC_CLIENT_LIB_LIB_UTILITY_UTILITY_SYNC_TIMER_H
Timer class for timeout monitoring.
Definition: sync_timer.h:24
SyncTimer()
Construct an instance of SyncTimer.
Definition: sync_timer.h:44
auto Start(std::chrono::milliseconds const timeout) noexcept -> TimerState
Function to start the timeout monitoring.
Definition: sync_timer.h:100
TimerState
Definition of different timer state during timeout monitoring.
Definition: sync_timer.h:39
void Stop() noexcept
Function to stop the current timeout monitoring.
Definition: sync_timer.h:133
std::chrono::time_point< Clock > TimePoint
Type alias for the clock time point.
Definition: sync_timer.h:34
std::mutex mutex_lock_
The mutex for the conditional variable.
Definition: sync_timer.h:148
ClockType Clock
Type alias for the clock type.
Definition: sync_timer.h:29
~SyncTimer()
Destruct an instance of SyncTimer.
Definition: sync_timer.h:49
void CancelWait()
Function to cancel the synchronous wait.
Definition: sync_timer.h:90
auto IsTimerActive()
Function to query if timer is running.
Definition: sync_timer.h:82
void WaitForTimeout(TimeoutCallback &&timeout_func, CancelCallback &&cancellation_func, std::chrono::milliseconds const timeout)
Helper function to wait for response with timeout monitoring.
Definition: sync_timer.h:70
bool start_running_
The flag to stop the current running timer.
Definition: sync_timer.h:158
std::condition_variable cond_var_
The conditional variable needed for synchronizing between start and stop of running timer.
Definition: sync_timer.h:143
bool exit_request_
The flag to terminate the wait.
Definition: sync_timer.h:153