10a816c5dSWilliam A. Kennington III #pragma once 20a816c5dSWilliam A. Kennington III 3e0f1d199SWilliam A. Kennington III #include <cerrno> 465db863eSWilliam A. Kennington III #include <cstdint> 5e0f1d199SWilliam A. Kennington III #include <cstdio> 6220b5dabSWilliam A. Kennington III #include <function2/function2.hpp> 748c42751SWilliam A. Kennington III #include <functional> 8*5320b1f5SWilliam A. Kennington III #include <memory> 9715c72f8SWilliam A. Kennington III #include <sdeventplus/event.hpp> 10e0f1d199SWilliam A. Kennington III #include <sdeventplus/internal/utils.hpp> 11*5320b1f5SWilliam A. Kennington III #include <sdeventplus/types.hpp> 12b555c4e6SWilliam A. Kennington III #include <stdplus/handle/managed.hpp> 130a816c5dSWilliam A. Kennington III #include <systemd/sd-bus.h> 140a816c5dSWilliam A. Kennington III #include <type_traits> 151e125d97SWilliam A. Kennington III #include <utility> 160a816c5dSWilliam A. Kennington III 170a816c5dSWilliam A. Kennington III namespace sdeventplus 180a816c5dSWilliam A. Kennington III { 190a816c5dSWilliam A. Kennington III namespace source 200a816c5dSWilliam A. Kennington III { 210a816c5dSWilliam A. Kennington III 228fd0cd4cSWilliam A. Kennington III /** @class Enabled 238fd0cd4cSWilliam A. Kennington III * @brief Mapping of sdeventplus source enable values to the sd-event 248fd0cd4cSWilliam A. Kennington III * equivalent 258fd0cd4cSWilliam A. Kennington III */ 268fd0cd4cSWilliam A. Kennington III enum class Enabled 278fd0cd4cSWilliam A. Kennington III { 288fd0cd4cSWilliam A. Kennington III Off = SD_EVENT_OFF, 298fd0cd4cSWilliam A. Kennington III On = SD_EVENT_ON, 308fd0cd4cSWilliam A. Kennington III OneShot = SD_EVENT_ONESHOT, 318fd0cd4cSWilliam A. Kennington III }; 328fd0cd4cSWilliam A. Kennington III 33*5320b1f5SWilliam A. Kennington III namespace detail 34*5320b1f5SWilliam A. Kennington III { 35*5320b1f5SWilliam A. Kennington III class BaseData; 36*5320b1f5SWilliam A. Kennington III } // namespace detail 37*5320b1f5SWilliam A. Kennington III 383c845caaSWilliam A. Kennington III /** @class Base 393c845caaSWilliam A. Kennington III * @brief The base class for all sources implementing common source methods 403c845caaSWilliam A. Kennington III * Not instantiated directly by end users 413c845caaSWilliam A. Kennington III */ 420a816c5dSWilliam A. Kennington III class Base 430a816c5dSWilliam A. Kennington III { 440a816c5dSWilliam A. Kennington III public: 45220b5dabSWilliam A. Kennington III using Callback = fu2::unique_function<void(Base& source)>; 4648c42751SWilliam A. Kennington III 47*5320b1f5SWilliam A. Kennington III Base(Base&& other) = default; 48*5320b1f5SWilliam A. Kennington III Base& operator=(Base&& other) = default; 49*5320b1f5SWilliam A. Kennington III virtual ~Base() = default; 5065db863eSWilliam A. Kennington III 513c845caaSWilliam A. Kennington III /** @brief Gets the underlying sd_event_source 523c845caaSWilliam A. Kennington III * 533c845caaSWilliam A. Kennington III * @return The sd_event_source 543c845caaSWilliam A. Kennington III */ 554863b96bSWilliam A. Kennington III sd_event_source* get() const; 563c845caaSWilliam A. Kennington III 573c845caaSWilliam A. Kennington III /** @brief Gets the associated Event object 583c845caaSWilliam A. Kennington III * 593c845caaSWilliam A. Kennington III * @return The Event 603c845caaSWilliam A. Kennington III */ 61715c72f8SWilliam A. Kennington III const Event& get_event() const; 62715c72f8SWilliam A. Kennington III 633c845caaSWilliam A. Kennington III /** @brief Gets the description of the source 643c845caaSWilliam A. Kennington III * 653c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 663c845caaSWilliam A. Kennington III * @return The c-string description or a nullptr if none exists 673c845caaSWilliam A. Kennington III */ 68d9fd9815SWilliam A. Kennington III const char* get_description() const; 693c845caaSWilliam A. Kennington III 703c845caaSWilliam A. Kennington III /** @brief Sets the description of the source 713c845caaSWilliam A. Kennington III * 723c845caaSWilliam A. Kennington III * @param[in] description - The c-string description 733c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 743c845caaSWilliam A. Kennington III */ 75d9fd9815SWilliam A. Kennington III void set_description(const char* description) const; 763c845caaSWilliam A. Kennington III 773c845caaSWilliam A. Kennington III /** @brief Sets the callback associated with the source to be performed 783c845caaSWilliam A. Kennington III * before the event loop goes to sleep, waiting for new events 793c845caaSWilliam A. Kennington III * 803c845caaSWilliam A. Kennington III * @param[in] callback - Function run for preparation of the source 813c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 823c845caaSWilliam A. Kennington III */ 8348c42751SWilliam A. Kennington III void set_prepare(Callback&& callback); 843c845caaSWilliam A. Kennington III 853c845caaSWilliam A. Kennington III /** @brief Whether or not the source has any pending events that have 863c845caaSWilliam A. Kennington III * not been dispatched yet. 873c845caaSWilliam A. Kennington III * 883c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 893c845caaSWilliam A. Kennington III * @return 'true' if the source has pending events 903c845caaSWilliam A. Kennington III * 'false' otherwise 913c845caaSWilliam A. Kennington III */ 928fd0cd4cSWilliam A. Kennington III bool get_pending() const; 933c845caaSWilliam A. Kennington III 943c845caaSWilliam A. Kennington III /** @brief Gets the priority of the source relative to other sources 953c845caaSWilliam A. Kennington III * The lower the priority the more important the source 963c845caaSWilliam A. Kennington III * 973c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 983c845caaSWilliam A. Kennington III * @return A 64 bit integer representing the dispatch priority 993c845caaSWilliam A. Kennington III */ 100d9fd9815SWilliam A. Kennington III int64_t get_priority() const; 1013c845caaSWilliam A. Kennington III 1023c845caaSWilliam A. Kennington III /** @brief Sets the priority of the source relative to other sources 1033c845caaSWilliam A. Kennington III * The lower the priority the more important the source 1043c845caaSWilliam A. Kennington III * 1053c845caaSWilliam A. Kennington III * @param[in] priority - A 64 bit integer representing the priority 1063c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1073c845caaSWilliam A. Kennington III */ 108d9fd9815SWilliam A. Kennington III void set_priority(int64_t priority) const; 1093c845caaSWilliam A. Kennington III 1103c845caaSWilliam A. Kennington III /** @brief Determines the enablement value of the source 1113c845caaSWilliam A. Kennington III * 1123c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1133c845caaSWilliam A. Kennington III * @return The enabled status of the source 1143c845caaSWilliam A. Kennington III */ 1158fd0cd4cSWilliam A. Kennington III Enabled get_enabled() const; 1163c845caaSWilliam A. Kennington III 1173c845caaSWilliam A. Kennington III /** @brief Sets the enablement value of the source 1183c845caaSWilliam A. Kennington III * 1193c845caaSWilliam A. Kennington III * @param[in] enabled - The new state of the source 1203c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1213c845caaSWilliam A. Kennington III */ 1228fd0cd4cSWilliam A. Kennington III void set_enabled(Enabled enabled) const; 12365db863eSWilliam A. Kennington III 1240a816c5dSWilliam A. Kennington III protected: 125cc6b12beSWilliam A. Kennington III Event event; 1260a816c5dSWilliam A. Kennington III 127bc4e4569SWilliam A. Kennington III /** @brief Constructs a basic event source wrapper 128bc4e4569SWilliam A. Kennington III * Owns the passed reference to the source 129bc4e4569SWilliam A. Kennington III * This ownership is exception safe and will properly free the 130bc4e4569SWilliam A. Kennington III * source in the case of an exception during construction 131bc4e4569SWilliam A. Kennington III * 132bc4e4569SWilliam A. Kennington III * @param[in] event - The event associated with the source 133bc4e4569SWilliam A. Kennington III * @param[in] source - The underlying sd_event_source wrapped 1342301d47fSWilliam A. Kennington III * @param[in] - Signifies that ownership is being transfered 135bc4e4569SWilliam A. Kennington III */ 136715c72f8SWilliam A. Kennington III Base(const Event& event, sd_event_source* source, std::false_type); 13748c42751SWilliam A. Kennington III 138*5320b1f5SWilliam A. Kennington III /** @brief Constructs a basic non-owning event source wrapper 139*5320b1f5SWilliam A. Kennington III * Does not own the passed reference to the source because 140*5320b1f5SWilliam A. Kennington III * this is meant to be used only as a reference inside an event 141*5320b1f5SWilliam A. Kennington III * source. 142*5320b1f5SWilliam A. Kennington III * @internal 143*5320b1f5SWilliam A. Kennington III * 144*5320b1f5SWilliam A. Kennington III * @param[in] other - The source wrapper to copy 145*5320b1f5SWilliam A. Kennington III * @param[in] - Signifies that this new copy is non-owning 146*5320b1f5SWilliam A. Kennington III */ 147*5320b1f5SWilliam A. Kennington III Base(const Base& other, sdeventplus::internal::NoOwn); 148*5320b1f5SWilliam A. Kennington III 149*5320b1f5SWilliam A. Kennington III /** @brief Sets the userdata of the source to the passed in source 150*5320b1f5SWilliam A. Kennington III * This needs to be called by all source implementors. 151*5320b1f5SWilliam A. Kennington III * 152*5320b1f5SWilliam A. Kennington III * @param[in] data - The data stored in the userdata slot. 153*5320b1f5SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 154*5320b1f5SWilliam A. Kennington III */ 155*5320b1f5SWilliam A. Kennington III void set_userdata(std::unique_ptr<detail::BaseData> data) const; 156*5320b1f5SWilliam A. Kennington III 157*5320b1f5SWilliam A. Kennington III /** @brief Get the heap allocated version of the Base 158*5320b1f5SWilliam A. Kennington III * 159*5320b1f5SWilliam A. Kennington III * @return A reference to the Base 160*5320b1f5SWilliam A. Kennington III */ 161*5320b1f5SWilliam A. Kennington III detail::BaseData& get_userdata() const; 162cc6b12beSWilliam A. Kennington III 163bc4e4569SWilliam A. Kennington III /** @brief Returns a reference to the prepare callback executed for this 164bc4e4569SWilliam A. Kennington III * source 165bc4e4569SWilliam A. Kennington III * 166bc4e4569SWilliam A. Kennington III * @return A reference to the callback, this should be checked to make sure 167bc4e4569SWilliam A. Kennington III * the callback is valid as there is no guarantee 168bc4e4569SWilliam A. Kennington III */ 169220b5dabSWilliam A. Kennington III Callback& get_prepare(); 170e0f1d199SWilliam A. Kennington III 171bc4e4569SWilliam A. Kennington III /** @brief A helper for subclasses to trivially wrap a c++ style callback 172bc4e4569SWilliam A. Kennington III * to be called from the sd-event c library 173bc4e4569SWilliam A. Kennington III * 174bc4e4569SWilliam A. Kennington III * @param[in] name - The name of the callback for use in error messages 175bc4e4569SWilliam A. Kennington III * @param[in] source - The sd_event_source provided by sd-event 176bc4e4569SWilliam A. Kennington III * @param[in] userdata - The userdata provided by sd-event 177bc4e4569SWilliam A. Kennington III * @param[in] args... - Extra arguments to pass to the callaback 178bc4e4569SWilliam A. Kennington III * @return An negative errno on error, or 0 on success 179bc4e4569SWilliam A. Kennington III */ 180*5320b1f5SWilliam A. Kennington III template <typename Callback, class Data, auto getter, typename... Args> 181e0f1d199SWilliam A. Kennington III static int sourceCallback(const char* name, sd_event_source*, 1821e125d97SWilliam A. Kennington III void* userdata, Args&&... args) 183e0f1d199SWilliam A. Kennington III { 184e0f1d199SWilliam A. Kennington III if (userdata == nullptr) 185e0f1d199SWilliam A. Kennington III { 186e0f1d199SWilliam A. Kennington III fprintf(stderr, "sdeventplus: %s: Missing userdata\n", name); 187e0f1d199SWilliam A. Kennington III return -EINVAL; 188e0f1d199SWilliam A. Kennington III } 189*5320b1f5SWilliam A. Kennington III Data& data = 190*5320b1f5SWilliam A. Kennington III static_cast<Data&>(*reinterpret_cast<detail::BaseData*>(userdata)); 191*5320b1f5SWilliam A. Kennington III Callback& callback = std::invoke(getter, data); 192*5320b1f5SWilliam A. Kennington III return internal::performCallback(name, callback, std::ref(data), 1931e125d97SWilliam A. Kennington III std::forward<Args>(args)...); 194e0f1d199SWilliam A. Kennington III } 195e0f1d199SWilliam A. Kennington III 19648c42751SWilliam A. Kennington III private: 197e04cb03bSWilliam A. Kennington III static void drop(sd_event_source*&& source, 198*5320b1f5SWilliam A. Kennington III const internal::SdEvent*& sdevent, bool& owned); 199e04cb03bSWilliam A. Kennington III 200*5320b1f5SWilliam A. Kennington III stdplus::Managed<sd_event_source*, const internal::SdEvent*, 201*5320b1f5SWilliam A. Kennington III bool>::Handle<drop> 202e04cb03bSWilliam A. Kennington III source; 2032d943eadSWilliam A. Kennington III 204*5320b1f5SWilliam A. Kennington III /** @brief A wrapper around deleting the heap allocated base class 205*5320b1f5SWilliam A. Kennington III * This is needed for calls from sd_event destroy callbacks. 206bc4e4569SWilliam A. Kennington III * 207*5320b1f5SWilliam A. Kennington III * @param[in] userdata - The provided userdata for the source 208bc4e4569SWilliam A. Kennington III */ 209*5320b1f5SWilliam A. Kennington III static void destroy_userdata(void* userdata); 210bc4e4569SWilliam A. Kennington III 211bc4e4569SWilliam A. Kennington III /** @brief A wrapper around the callback that can be called from sd-event 212bc4e4569SWilliam A. Kennington III * 213bc4e4569SWilliam A. Kennington III * @param[in] source - The sd_event_source associated with the call 214bc4e4569SWilliam A. Kennington III * @param[in] userdata - The provided userdata for the source 215bc4e4569SWilliam A. Kennington III * @return 0 on success or a negative errno otherwise 216bc4e4569SWilliam A. Kennington III */ 217e0f1d199SWilliam A. Kennington III static int prepareCallback(sd_event_source* source, void* userdata); 2180a816c5dSWilliam A. Kennington III }; 2190a816c5dSWilliam A. Kennington III 220*5320b1f5SWilliam A. Kennington III namespace detail 221*5320b1f5SWilliam A. Kennington III { 222*5320b1f5SWilliam A. Kennington III 223*5320b1f5SWilliam A. Kennington III class BaseData : public Base 224*5320b1f5SWilliam A. Kennington III { 225*5320b1f5SWilliam A. Kennington III private: 226*5320b1f5SWilliam A. Kennington III Base::Callback prepare; 227*5320b1f5SWilliam A. Kennington III 228*5320b1f5SWilliam A. Kennington III public: 229*5320b1f5SWilliam A. Kennington III BaseData(const Base& base); 230*5320b1f5SWilliam A. Kennington III 231*5320b1f5SWilliam A. Kennington III friend Base; 232*5320b1f5SWilliam A. Kennington III }; 233*5320b1f5SWilliam A. Kennington III 234*5320b1f5SWilliam A. Kennington III } // namespace detail 235*5320b1f5SWilliam A. Kennington III 2360a816c5dSWilliam A. Kennington III } // namespace source 2370a816c5dSWilliam A. Kennington III } // namespace sdeventplus 238