xref: /openbmc/sdeventplus/src/sdeventplus/source/time.hpp (revision a8c11e3ca342b090aec615c832b85686bd4655f6)
1 #pragma once
2 
3 #include <systemd/sd-event.h>
4 
5 #include <function2/function2.hpp>
6 #include <sdeventplus/clock.hpp>
7 #include <sdeventplus/source/base.hpp>
8 #include <sdeventplus/types.hpp>
9 
10 #include <cstdint>
11 
12 namespace sdeventplus
13 {
14 namespace source
15 {
16 
17 namespace detail
18 {
19 template <ClockId Id>
20 class TimeData;
21 } // namespace detail
22 
23 /** @class Time<ClockId>
24  *  @brief A wrapper around the sd_event_source time type
25  *         See sd_event_add_time(3) for more information
26  */
27 template <ClockId Id>
28 class Time : public Base
29 {
30   public:
31     /** @brief Type used as the basis for absolute clock times */
32     using TimePoint = typename Clock<Id>::time_point;
33     /** @brief Type used to define the accuracy of the time source */
34     using Accuracy = SdEventDuration;
35     /** @brief Type of the user provided callback function */
36     using Callback = fu2::unique_function<void(Time& source, TimePoint time)>;
37 
38     /** @brief Creates a new time event source on the provided event loop
39      *         This type of source defaults to Enabled::Oneshot, and needs to be
40      *         reconfigured upon each callback.
41      *
42      *  @param[in] event    - The event to attach the handler
43      *  @param[in] time     - Absolute time when the callback should be executed
44      *  @param[in] accuracy - Optional amount of error tolerable in time source
45      *  @param[in] callback - The function executed on event dispatch
46      *  @throws SdEventError for underlying sd_event errors
47      */
48     Time(const Event& event, TimePoint time, Accuracy accuracy,
49          Callback&& callback);
50 
51     /** @brief Constructs a non-owning time source handler
52      *         Does not own the passed reference to the source because
53      *         this is meant to be used only as a reference inside an event
54      *         source.
55      *  @internal
56      *
57      *  @param[in] other - The source wrapper to copy
58      *  @param[in]       - Signifies that this new copy is non-owning
59      *  @throws SdEventError for underlying sd_event errors
60      */
61     Time(const Time& other, sdeventplus::internal::NoOwn);
62 
63     /** @brief Sets the callback
64      *
65      *  @param[in] callback - The function executed on event dispatch
66      */
67     void set_callback(Callback&& callback);
68 
69     /** @brief Gets the absolute time when the time source expires
70      *
71      *  @throws SdEventError for underlying sd_event errors
72      *  @return Absolute time as an std::chrono::time_point
73      */
74     TimePoint get_time() const;
75 
76     /** @brief Sets the absolute time when the time source will expire
77      *
78      *  @param[in] time - Absolute time as an std::chrono::time_point
79      *  @throws SdEventError for underlying sd_event errors
80      */
81     void set_time(TimePoint time) const;
82 
83     /** @brief Gets the accuracy of the time source
84      *
85      *  @throws SdEventError for underlying sd_event errors
86      *  @return Accuracy as an std::chrono::duration
87      */
88     Accuracy get_accuracy() const;
89 
90     /** @brief Sets the accuracy of the time source
91      *
92      *  @param[in] accuracy - Accuracy as std::chrono::duration
93      *  @throws SdEventError for underlying sd_event errors
94      */
95     void set_accuracy(Accuracy accuracy) const;
96 
97   private:
98     /** @brief Returns a reference to the source owned time
99      *
100      *  @return A reference to the time
101      */
102     detail::TimeData<Id>& get_userdata() const;
103 
104     /** @brief Returns a reference to the callback executed for this source
105      *
106      *  @return A reference to the callback
107      */
108     Callback& get_callback();
109 
110     /** @brief Creates a new time source attached to the Event
111      *
112      *  @param[in] event    - The event to attach the handler
113      *  @param[in] time     - Absolute time when the callback should be executed
114      *  @param[in] accuracy - Optional amount of error tolerable in time source
115      *  @throws SdEventError for underlying sd_event errors
116      *  @return A new sd_event_source
117      */
118     static sd_event_source* create_source(const Event& event, TimePoint time,
119                                           Accuracy accuracy);
120 
121     /** @brief A wrapper around the callback that can be called from sd-event
122      *
123      *  @param[in] source   - The sd_event_source associated with the call
124      *  @param[in] userdata - The provided userdata for the source
125      *  @return 0 on success or a negative errno otherwise
126      */
127     static int timeCallback(sd_event_source* source, uint64_t usec,
128                             void* userdata);
129 };
130 
131 namespace detail
132 {
133 
134 template <ClockId Id>
135 class TimeData : public Time<Id>, public BaseData
136 {
137   private:
138     typename Time<Id>::Callback callback;
139 
140   public:
141     TimeData(const Time<Id>& base, typename Time<Id>::Callback&& callback);
142 
143     friend Time<Id>;
144 };
145 
146 } // namespace detail
147 
148 } // namespace source
149 } // namespace sdeventplus
150