blob: e6b069330cdd54903d3685690ea1914774c6a5e5 [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
Patrick Venture09eebe32017-08-11 15:23:17 -070059 void clearExpired(void)
60 {
61 expire = false;
62 }
63
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +053064 /** @brief Tells whether the timer is expired or not */
65 inline auto expired() const
66 {
67 return expire;
68 }
69
70 /** @brief Returns the current Timer enablement type */
71 int getEnabled() const;
72
73 /** @brief Enables / disables the timer.
74 * <T> is an integral constant boolean
75 */
76 template <typename T> void setEnabled()
77 {
78 constexpr auto type = T::value ? SD_EVENT_ONESHOT : SD_EVENT_OFF;
79 return setEnabled(type);
80 }
81
82 /** @brief Returns time remaining in usec before expiration
83 * which is an offset to current steady clock
84 */
85 std::chrono::microseconds getRemaining() const;
86
87 /** @brief Starts the timer with specified expiration value.
88 * std::steady_clock is used for base time.
89 *
90 * @param[in] usec - Microseconds from the current time
91 * before expiration.
92 *
93 * @return None.
94 *
95 * @error Throws exception
96 */
97 void start(std::chrono::microseconds usec);
98
99 /** @brief Gets the current time from steady clock */
100 static std::chrono::microseconds getCurrentTime();
101
102 private:
103 /** @brief Reference to sd_event unique pointer */
104 EventPtr& event;
105
106 /** @brief event source */
107 EventSourcePtr eventSource;
108
109 /** @brief Set to true when the timeoutHandler is called into */
110 bool expire = false;
111
Vishwanatha Subbanna8c5a2292017-05-30 15:34:23 +0530112 /** @brief Optional function to call on timer expiration
113 * This is called from timeout handler.
114 */
115 std::function<void()> userCallBack;
116
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +0530117 /** @brief Initializes the timer object with infinite
118 * expiration time and sets up the callback handler
119 *
120 * @return None.
121 *
122 * @error Throws exception
123 */
124 void initialize();
125
126 /** @brief Callback function when timer goes off
127 *
128 * @param[in] eventSource - Source of the event
129 * @param[in] usec - time in microseconds
130 * @param[in] userData - User data pointer
131 *
132 */
133 static int timeoutHandler(sd_event_source* eventSource,
134 uint64_t usec, void* userData);
135
136 /** @brief Enables / disables the timer
137 *
138 * @param[in] type - Timer type.
139 * This implementation uses only SD_EVENT_OFF
140 * and SD_EVENT_ONESHOT
141 */
142 void setEnabled(int type);
143};
144
145} // namespace watchdog
146} // namespace phosphor