blob: 28222a23ac418c03c19ef3f2ca21716b8f8abc56 [file] [log] [blame]
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +05301#pragma once
2
Patrick Venture8f6c5152018-09-11 17:45:33 -07003#include <systemd/sd-event.h>
4
5#include <chrono>
Brad Bishopbe9bec12018-02-21 12:51:24 -05006#include <functional>
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +05307#include <memory>
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +05308namespace phosphor
9{
10namespace watchdog
11{
12
13/* Need a custom deleter for freeing up sd_event */
14struct EventDeleter
15{
16 void operator()(sd_event* event) const
17 {
18 event = sd_event_unref(event);
19 }
20};
21using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
22
23/* Need a custom deleter for freeing up sd_event_source */
24struct EventSourceDeleter
25{
26 void operator()(sd_event_source* eventSource) const
27 {
28 eventSource = sd_event_source_unref(eventSource);
29 }
30};
31using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>;
32
33/** @class Timer
34 * @brief Manages starting timers and handling timeouts
35 */
36class Timer
37{
Patrick Venture8f6c5152018-09-11 17:45:33 -070038 public:
39 Timer() = delete;
40 ~Timer() = default;
41 Timer(const Timer&) = delete;
42 Timer& operator=(const Timer&) = delete;
43 Timer(Timer&&) = delete;
44 Timer& operator=(Timer&&) = delete;
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +053045
Patrick Venture8f6c5152018-09-11 17:45:33 -070046 /** @brief Constructs timer object
47 *
48 * @param[in] event - sd_event unique pointer
49 * @param[in] userCallBack - Optional function callback
50 * for timer expiration
51 */
52 Timer(EventPtr& event, std::function<void()> userCallBack = nullptr) :
53 event(event), userCallBack(userCallBack)
54 {
55 // Initialize the timer
56 initialize();
57 }
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +053058
Patrick Venture8f6c5152018-09-11 17:45:33 -070059 void clearExpired(void)
60 {
61 expire = false;
62 }
Patrick Venture09eebe32017-08-11 15:23:17 -070063
Patrick Venture8f6c5152018-09-11 17:45:33 -070064 /** @brief Tells whether the timer is expired or not */
65 inline auto expired() const
66 {
67 return expire;
68 }
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +053069
Patrick Venture8f6c5152018-09-11 17:45:33 -070070 /** @brief Returns the current Timer enablement type */
71 int getEnabled() const;
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +053072
Patrick Venture8f6c5152018-09-11 17:45:33 -070073 /** @brief Enables / disables the timer.
74 * <T> is an integral constant boolean
75 */
76 template <typename T>
77 void setEnabled()
78 {
79 constexpr auto type = T::value ? SD_EVENT_ONESHOT : SD_EVENT_OFF;
80 return setEnabled(type);
81 }
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +053082
Patrick Venture8f6c5152018-09-11 17:45:33 -070083 /** @brief Returns time remaining in usec before expiration
84 * which is an offset to current steady clock
85 */
86 std::chrono::microseconds getRemaining() const;
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +053087
Patrick Venture8f6c5152018-09-11 17:45:33 -070088 /** @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);
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +053099
Patrick Venture8f6c5152018-09-11 17:45:33 -0700100 /** @brief Gets the current time from steady clock */
101 static std::chrono::microseconds getCurrentTime();
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +0530102
Patrick Venture8f6c5152018-09-11 17:45:33 -0700103 private:
104 /** @brief Reference to sd_event unique pointer */
105 EventPtr& event;
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +0530106
Patrick Venture8f6c5152018-09-11 17:45:33 -0700107 /** @brief event source */
108 EventSourcePtr eventSource;
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +0530109
Patrick Venture8f6c5152018-09-11 17:45:33 -0700110 /** @brief Set to true when the timeoutHandler is called into */
111 bool expire = false;
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +0530112
Patrick Venture8f6c5152018-09-11 17:45:33 -0700113 /** @brief Optional function to call on timer expiration
114 * This is called from timeout handler.
115 */
116 std::function<void()> userCallBack;
Vishwanatha Subbanna8c5a2292017-05-30 15:34:23 +0530117
Patrick Venture8f6c5152018-09-11 17:45:33 -0700118 /** @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();
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +0530126
Patrick Venture8f6c5152018-09-11 17:45:33 -0700127 /** @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, uint64_t usec,
135 void* userData);
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +0530136
Patrick Venture8f6c5152018-09-11 17:45:33 -0700137 /** @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);
Vishwanatha Subbanna7e146552017-05-29 17:03:33 +0530144};
145
146} // namespace watchdog
147} // namespace phosphor