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