1 #pragma once 2 3 #include <systemd/sd-event.h> 4 5 #include <function2/function2.hpp> 6 #include <sdeventplus/internal/sdevent.hpp> 7 #include <sdeventplus/source/base.hpp> 8 #include <sdeventplus/types.hpp> 9 10 #include <type_traits> 11 12 namespace sdeventplus 13 { 14 namespace source 15 { 16 17 namespace detail 18 { 19 class EventBaseData; 20 } // namespace detail 21 22 /** @class EventBase 23 * @brief A wrapper around the sd_event_source defer type 24 * See sd_event_add_defer(3) for more information 25 * There are multiple types of defer sources, instantiate 26 * Defer, Post, or Exit depending on the required event. 27 */ 28 class EventBase : public Base 29 { 30 public: 31 using Callback = fu2::unique_function<void(EventBase& source)>; 32 33 /** @brief Sets the callback 34 * 35 * @param[in] callback - The function executed on event dispatch 36 */ 37 void set_callback(Callback&& callback); 38 39 /** @brief Constructs a non-owning event source handler 40 * Does not own the passed reference to the source because 41 * this is meant to be used only as a reference inside an event 42 * source. 43 * @internal 44 * 45 * @param[in] other - The source wrapper to copy 46 * @param[in] - Signifies that this new copy is non-owning 47 */ 48 EventBase(const EventBase& other, sdeventplus::internal::NoOwn); 49 50 protected: 51 using CreateFunc = decltype(&internal::SdEvent::sd_event_add_exit); 52 53 /** @brief Adds a new event source handler to the Event 54 * This type of source defaults to Enabled::Oneshot, and needs to be 55 * reconfigured upon each callback. 56 * 57 * @param[in] name - The name identifying the create function 58 * @param[in] create - The SdEvent function called to create the source 59 * @param[in] event - The event to attach the handler 60 * @param[in] callback - The function executed on event dispatch 61 */ 62 EventBase(const char* name, CreateFunc create, const Event& event, 63 Callback&& callback); 64 65 private: 66 /** @brief Returns a reference to the source owned event 67 * 68 * @return A reference to the event 69 */ 70 detail::EventBaseData& get_userdata() const; 71 72 /** @brief Returns a reference to the callback executed for this source 73 * 74 * @return A reference to the callback 75 */ 76 Callback& get_callback(); 77 78 /** @brief Creates a new source attached to the Event 79 * 80 * @param[in] name - The name identifying the create function 81 * @param[in] create - The SdEvent function called to create the source 82 * @param[in] event - The event to attach the handler 83 * @throws SdEventError for underlying sd_event errors 84 * @return A new sd_event_source 85 */ 86 static sd_event_source* create_source(const char* name, CreateFunc create, 87 const Event& event); 88 89 /** @brief A wrapper around the callback that can be called from sd-event 90 * 91 * @param[in] source - The sd_event_source associated with the call 92 * @param[in] userdata - The provided userdata for the source 93 * @return 0 on success or a negative errno otherwise 94 */ 95 static int eventCallback(sd_event_source* source, void* userdata); 96 }; 97 98 namespace detail 99 { 100 101 class EventBaseData : public EventBase, public BaseData 102 { 103 private: 104 EventBase::Callback callback; 105 106 public: 107 EventBaseData(const EventBase& base, EventBase::Callback&& callback); 108 109 friend EventBase; 110 }; 111 112 } // namespace detail 113 114 class Defer : public EventBase 115 { 116 public: 117 /** @brief Adds a new defer source handler to the Event 118 * Executes the callback upon events occurring 119 * 120 * @param[in] event - The event to attach the handler 121 * @param[in] callback - The function executed on event dispatch 122 * @throws SdEventError for underlying sd_event errors 123 */ 124 Defer(const Event& event, Callback&& Callback); 125 }; 126 127 class Post : public EventBase 128 { 129 public: 130 /** @brief Adds a new post source handler to the Event 131 * Executes the callback upon events occurring 132 * 133 * @param[in] event - The event to attach the handler 134 * @param[in] callback - The function executed on event dispatch 135 * @throws SdEventError for underlying sd_event errors 136 */ 137 Post(const Event& event, Callback&& callback); 138 }; 139 140 class Exit : public EventBase 141 { 142 public: 143 /** @brief Adds a new exit source handler to the Event 144 * Executes the callback upon events occurring 145 * 146 * @param[in] event - The event to attach the handler 147 * @param[in] callback - The function executed on event dispatch 148 * @throws SdEventError for underlying sd_event errors 149 */ 150 Exit(const Event& event, Callback&& callback); 151 }; 152 153 } // namespace source 154 } // namespace sdeventplus 155