blob: 2ade017d8bb2e4c559630f0fc97a7a28e25a0531 [file] [log] [blame]
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +05301#pragma once
2
3#include <memory>
4#include <chrono>
5#include <systemd/sd-event.h>
6namespace phosphor
7{
8namespace watchdog
9{
10
11/* Need a custom deleter for freeing up sd_event */
12struct EventDeleter
13{
14 void operator()(sd_event* event) const
15 {
16 event = sd_event_unref(event);
17 }
18};
19using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
20
21/* Need a custom deleter for freeing up sd_event_source */
22struct EventSourceDeleter
23{
24 void operator()(sd_event_source* eventSource) const
25 {
26 eventSource = sd_event_source_unref(eventSource);
27 }
28};
29using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>;
30
31/** @class Timer
32 * @brief Manages starting timers and handling timeouts
33 */
34class Timer
35{
36 public:
37 Timer() = delete;
38 ~Timer() = default;
39 Timer(const Timer&) = delete;
40 Timer& operator=(const Timer&) = delete;
41 Timer(Timer&&) = delete;
42 Timer& operator=(Timer&&) = delete;
43
44 /** @brief Constructs timer object
45 *
Vishwanatha Subbanna8c5a2292017-05-30 15:34:23 +053046 * @param[in] event - sd_event unique pointer
47 * @param[in] userCallBack - Optional function callback
48 * for timer expiration
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +053049 */
Vishwanatha Subbanna8c5a2292017-05-30 15:34:23 +053050 Timer(EventPtr& event,
51 std::function<void()> userCallBack = nullptr)
52 : event(event),
53 userCallBack(userCallBack)
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +053054 {
55 // Initialize the timer
56 initialize();
57 }
58
59 /** @brief Tells whether the timer is expired or not */
60 inline auto expired() const
61 {
62 return expire;
63 }
64
65 /** @brief Returns the current Timer enablement type */
66 int getEnabled() const;
67
68 /** @brief Enables / disables the timer.
69 * <T> is an integral constant boolean
70 */
71 template <typename T> void setEnabled()
72 {
73 constexpr auto type = T::value ? SD_EVENT_ONESHOT : SD_EVENT_OFF;
74 return setEnabled(type);
75 }
76
77 /** @brief Returns time remaining in usec before expiration
78 * which is an offset to current steady clock
79 */
80 std::chrono::microseconds getRemaining() const;
81
82 /** @brief Starts the timer with specified expiration value.
83 * std::steady_clock is used for base time.
84 *
85 * @param[in] usec - Microseconds from the current time
86 * before expiration.
87 *
88 * @return None.
89 *
90 * @error Throws exception
91 */
92 void start(std::chrono::microseconds usec);
93
94 /** @brief Gets the current time from steady clock */
95 static std::chrono::microseconds getCurrentTime();
96
97 private:
98 /** @brief Reference to sd_event unique pointer */
99 EventPtr& event;
100
101 /** @brief event source */
102 EventSourcePtr eventSource;
103
104 /** @brief Set to true when the timeoutHandler is called into */
105 bool expire = false;
106
Vishwanatha Subbanna8c5a2292017-05-30 15:34:23 +0530107 /** @brief Optional function to call on timer expiration
108 * This is called from timeout handler.
109 */
110 std::function<void()> userCallBack;
111
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +0530112 /** @brief Initializes the timer object with infinite
113 * expiration time and sets up the callback handler
114 *
115 * @return None.
116 *
117 * @error Throws exception
118 */
119 void initialize();
120
121 /** @brief Callback function when timer goes off
122 *
123 * @param[in] eventSource - Source of the event
124 * @param[in] usec - time in microseconds
125 * @param[in] userData - User data pointer
126 *
127 */
128 static int timeoutHandler(sd_event_source* eventSource,
129 uint64_t usec, void* userData);
130
131 /** @brief Enables / disables the timer
132 *
133 * @param[in] type - Timer type.
134 * This implementation uses only SD_EVENT_OFF
135 * and SD_EVENT_ONESHOT
136 */
137 void setEnabled(int type);
138};
139
140} // namespace watchdog
141} // namespace phosphor