blob: 3b7783b7976de2d2f7262a5d632fcaed867cc43e [file] [log] [blame]
Matt Spinler2de67cf2017-04-27 11:07:53 -05001#pragma once
2
3#include <chrono>
4#include <functional>
5#include <memory>
William A. Kennington III1cfc2f12018-10-19 17:29:46 -07006#include <sdeventplus/event.hpp>
Matt Spinlere824f982017-05-11 10:07:55 -05007#include "event.hpp"
Matt Spinler2de67cf2017-04-27 11:07:53 -05008
9namespace phosphor
10{
11namespace fan
12{
13namespace util
14{
15
Matt Spinler2de67cf2017-04-27 11:07:53 -050016
17/**
18 * @class Timer
19 *
20 * This class implements a simple timer that runs an arbitrary
21 * function on expiration. The timeout value is set in microseconds.
22 * It can be stopped while it is running, and queried to see if it is
23 * running.
24 *
25 * If started with the 'repeating' argument, it will keep calling the
26 * callback function every <timeout> microseconds. If started with the
27 * 'oneshot' argument, it will just call the callback function one time.
28 *
29 * It needs an sd_event loop to function.
30 */
31class Timer
32{
33 public:
34
35 enum class TimerType
36 {
37 oneshot,
38 repeating
39 };
40
41 Timer() = delete;
42 Timer(const Timer&) = delete;
43 Timer& operator=(const Timer&) = delete;
44 Timer(Timer&&) = default;
45 Timer& operator=(Timer&&) = default;
46
47 /**
48 * @brief Constructs timer object
49 *
William A. Kennington III1cfc2f12018-10-19 17:29:46 -070050 * @param[in] event - Event loop reference, previously created
Matt Spinler2de67cf2017-04-27 11:07:53 -050051 * @param[in] callbackFunc - The function to call on timer expiration
52 */
William A. Kennington III1cfc2f12018-10-19 17:29:46 -070053 Timer(const sdeventplus::Event& event,
Matt Spinler2de67cf2017-04-27 11:07:53 -050054 std::function<void()> callbackFunc);
55
56 /**
57 * @brief Destructor
58 */
59 ~Timer();
60
61 /**
62 * @brief Starts the timer
63 *
64 * The input is an offset from the current steady clock.
65 *
66 * @param[in] usec - the timeout value in microseconds
67 * @param[in] type - either a oneshot, or repeating
68 */
69 void start(std::chrono::microseconds usec,
70 TimerType type = TimerType::oneshot);
71
72 /**
73 * @brief Stop the timer
74 */
75 void stop();
76
77 /**
78 * @brief Returns true if the timer is running
79 */
80 bool running();
81
82 /**
83 * @brief Returns the timeout value
84 *
85 * @return - the last value sent in via start().
86 *
87 * Could be used to restart the timer with the same
88 * timeout. i.e. start(getTimeout());
89 */
90 inline auto getTimeout() const
91 {
92 return timeout;
93 }
94
95 /**
96 * @brief Returns the timer type
97 */
98 inline auto getType() const
99 {
100 return type;
101 }
102
103 private:
104
105 /**
106 * @brief Callback function when timer goes off
107 *
108 * Calls the callback function passed in by the user.
109 *
110 * @param[in] eventSource - Source of the event
111 * @param[in] usec - time in micro seconds
112 * @param[in] userData - User data pointer
113 */
114 static int timeoutHandler(sd_event_source* eventSource,
115 uint64_t usec, void* userData);
116
117 /**
118 * @brief Gets the current time from the steady clock
119 */
120 std::chrono::microseconds getTime();
121
122 /**
123 * @brief Wrapper around sd_event_source_set_enabled
124 *
125 * @param[in] action - either SD_EVENT_OFF, SD_EVENT_ON,
126 * or SD_EVENT_ONESHOT
127 */
128 void setTimer(int action);
129
130
131 /**
132 * @brief Sets the expiration time for the timer
133 *
134 * Sets it to timeout microseconds in the future
135 */
136 void setTimeout();
137
138 /**
Matt Spinler2de67cf2017-04-27 11:07:53 -0500139 * @brief Source of events
140 */
Matt Spinlere824f982017-05-11 10:07:55 -0500141 phosphor::fan::event::EventSourcePtr eventSource;
Matt Spinler2de67cf2017-04-27 11:07:53 -0500142
143 /**
144 * @brief Either 'repeating' or 'oneshot'
145 */
146 TimerType type = TimerType::oneshot;
147
148 /**
149 * @brief The function to call when the timer expires
150 */
151 std::function<void()> callback;
152
153 /**
154 * @brief What the timer was set to run for
155 *
156 * Not cleared on timer expiration
157 */
158 std::chrono::microseconds timeout;
159};
160
161}
162}
163}