blob: 49580d7017f8dd7d0515f7651703b37f1145880d [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 *
46 * @param[in] event - sd_event unique pointer reference
47 */
48 Timer(EventPtr& event)
49 : event(event)
50 {
51 // Initialize the timer
52 initialize();
53 }
54
55 /** @brief Tells whether the timer is expired or not */
56 inline auto expired() const
57 {
58 return expire;
59 }
60
61 /** @brief Returns the current Timer enablement type */
62 int getEnabled() const;
63
64 /** @brief Enables / disables the timer.
65 * <T> is an integral constant boolean
66 */
67 template <typename T> void setEnabled()
68 {
69 constexpr auto type = T::value ? SD_EVENT_ONESHOT : SD_EVENT_OFF;
70 return setEnabled(type);
71 }
72
73 /** @brief Returns time remaining in usec before expiration
74 * which is an offset to current steady clock
75 */
76 std::chrono::microseconds getRemaining() const;
77
78 /** @brief Starts the timer with specified expiration value.
79 * std::steady_clock is used for base time.
80 *
81 * @param[in] usec - Microseconds from the current time
82 * before expiration.
83 *
84 * @return None.
85 *
86 * @error Throws exception
87 */
88 void start(std::chrono::microseconds usec);
89
90 /** @brief Gets the current time from steady clock */
91 static std::chrono::microseconds getCurrentTime();
92
93 private:
94 /** @brief Reference to sd_event unique pointer */
95 EventPtr& event;
96
97 /** @brief event source */
98 EventSourcePtr eventSource;
99
100 /** @brief Set to true when the timeoutHandler is called into */
101 bool expire = false;
102
103 /** @brief Initializes the timer object with infinite
104 * expiration time and sets up the callback handler
105 *
106 * @return None.
107 *
108 * @error Throws exception
109 */
110 void initialize();
111
112 /** @brief Callback function when timer goes off
113 *
114 * @param[in] eventSource - Source of the event
115 * @param[in] usec - time in microseconds
116 * @param[in] userData - User data pointer
117 *
118 */
119 static int timeoutHandler(sd_event_source* eventSource,
120 uint64_t usec, void* userData);
121
122 /** @brief Enables / disables the timer
123 *
124 * @param[in] type - Timer type.
125 * This implementation uses only SD_EVENT_OFF
126 * and SD_EVENT_ONESHOT
127 */
128 void setEnabled(int type);
129};
130
131} // namespace watchdog
132} // namespace phosphor