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