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