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> 648c42751SWilliam A. Kennington III #include <functional> 7715c72f8SWilliam A. Kennington III #include <sdeventplus/event.hpp> 80a816c5dSWilliam A. Kennington III #include <sdeventplus/internal/sdref.hpp> 9e0f1d199SWilliam A. Kennington III #include <sdeventplus/internal/utils.hpp> 100a816c5dSWilliam A. Kennington III #include <systemd/sd-bus.h> 110a816c5dSWilliam A. Kennington III #include <type_traits> 120a816c5dSWilliam A. Kennington III 130a816c5dSWilliam A. Kennington III namespace sdeventplus 140a816c5dSWilliam A. Kennington III { 150a816c5dSWilliam A. Kennington III namespace source 160a816c5dSWilliam A. Kennington III { 170a816c5dSWilliam A. Kennington III 188fd0cd4cSWilliam A. Kennington III /** @class Enabled 198fd0cd4cSWilliam A. Kennington III * @brief Mapping of sdeventplus source enable values to the sd-event 208fd0cd4cSWilliam A. Kennington III * equivalent 218fd0cd4cSWilliam A. Kennington III */ 228fd0cd4cSWilliam A. Kennington III enum class Enabled 238fd0cd4cSWilliam A. Kennington III { 248fd0cd4cSWilliam A. Kennington III Off = SD_EVENT_OFF, 258fd0cd4cSWilliam A. Kennington III On = SD_EVENT_ON, 268fd0cd4cSWilliam A. Kennington III OneShot = SD_EVENT_ONESHOT, 278fd0cd4cSWilliam A. Kennington III }; 288fd0cd4cSWilliam A. Kennington III 293c845caaSWilliam A. Kennington III /** @class Base 303c845caaSWilliam A. Kennington III * @brief The base class for all sources implementing common source methods 313c845caaSWilliam A. Kennington III * Not instantiated directly by end users 323c845caaSWilliam A. Kennington III */ 330a816c5dSWilliam A. Kennington III class Base 340a816c5dSWilliam A. Kennington III { 350a816c5dSWilliam A. Kennington III public: 3648c42751SWilliam A. Kennington III using Callback = std::function<void(Base& source)>; 3748c42751SWilliam A. Kennington III 3865db863eSWilliam A. Kennington III virtual ~Base(); 3965db863eSWilliam A. Kennington III 403c845caaSWilliam A. Kennington III /** @brief Gets the underlying sd_event_source 413c845caaSWilliam A. Kennington III * 423c845caaSWilliam A. Kennington III * @return The sd_event_source 433c845caaSWilliam A. Kennington III */ 444863b96bSWilliam A. Kennington III sd_event_source* get() const; 453c845caaSWilliam A. Kennington III 463c845caaSWilliam A. Kennington III /** @brief Gets the associated Event object 473c845caaSWilliam A. Kennington III * 483c845caaSWilliam A. Kennington III * @return The Event 493c845caaSWilliam A. Kennington III */ 50715c72f8SWilliam A. Kennington III const Event& get_event() const; 51715c72f8SWilliam A. Kennington III 523c845caaSWilliam A. Kennington III /** @brief Gets the description of the source 533c845caaSWilliam A. Kennington III * 543c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 553c845caaSWilliam A. Kennington III * @return The c-string description or a nullptr if none exists 563c845caaSWilliam A. Kennington III */ 57d9fd9815SWilliam A. Kennington III const char* get_description() const; 583c845caaSWilliam A. Kennington III 593c845caaSWilliam A. Kennington III /** @brief Sets the description of the source 603c845caaSWilliam A. Kennington III * 613c845caaSWilliam A. Kennington III * @param[in] description - The c-string description 623c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 633c845caaSWilliam A. Kennington III */ 64d9fd9815SWilliam A. Kennington III void set_description(const char* description) const; 653c845caaSWilliam A. Kennington III 663c845caaSWilliam A. Kennington III /** @brief Sets the callback associated with the source to be performed 673c845caaSWilliam A. Kennington III * before the event loop goes to sleep, waiting for new events 683c845caaSWilliam A. Kennington III * 693c845caaSWilliam A. Kennington III * @param[in] callback - Function run for preparation of the source 703c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 713c845caaSWilliam A. Kennington III */ 7248c42751SWilliam A. Kennington III void set_prepare(Callback&& callback); 733c845caaSWilliam A. Kennington III 743c845caaSWilliam A. Kennington III /** @brief Whether or not the source has any pending events that have 753c845caaSWilliam A. Kennington III * not been dispatched yet. 763c845caaSWilliam A. Kennington III * 773c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 783c845caaSWilliam A. Kennington III * @return 'true' if the source has pending events 793c845caaSWilliam A. Kennington III * 'false' otherwise 803c845caaSWilliam A. Kennington III */ 818fd0cd4cSWilliam A. Kennington III bool get_pending() const; 823c845caaSWilliam A. Kennington III 833c845caaSWilliam A. Kennington III /** @brief Gets the priority of the source relative to other sources 843c845caaSWilliam A. Kennington III * The lower the priority the more important the source 853c845caaSWilliam A. Kennington III * 863c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 873c845caaSWilliam A. Kennington III * @return A 64 bit integer representing the dispatch priority 883c845caaSWilliam A. Kennington III */ 89d9fd9815SWilliam A. Kennington III int64_t get_priority() const; 903c845caaSWilliam A. Kennington III 913c845caaSWilliam A. Kennington III /** @brief Sets the priority of the source relative to other sources 923c845caaSWilliam A. Kennington III * The lower the priority the more important the source 933c845caaSWilliam A. Kennington III * 943c845caaSWilliam A. Kennington III * @param[in] priority - A 64 bit integer representing the priority 953c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 963c845caaSWilliam A. Kennington III */ 97d9fd9815SWilliam A. Kennington III void set_priority(int64_t priority) const; 983c845caaSWilliam A. Kennington III 993c845caaSWilliam A. Kennington III /** @brief Determines the enablement value of the source 1003c845caaSWilliam A. Kennington III * 1013c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1023c845caaSWilliam A. Kennington III * @return The enabled status of the source 1033c845caaSWilliam A. Kennington III */ 1048fd0cd4cSWilliam A. Kennington III Enabled get_enabled() const; 1053c845caaSWilliam A. Kennington III 1063c845caaSWilliam A. Kennington III /** @brief Sets the enablement value of the source 1073c845caaSWilliam A. Kennington III * 1083c845caaSWilliam A. Kennington III * @param[in] enabled - The new state of the source 1093c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1103c845caaSWilliam A. Kennington III */ 1118fd0cd4cSWilliam A. Kennington III void set_enabled(Enabled enabled) const; 11265db863eSWilliam A. Kennington III 1130a816c5dSWilliam A. Kennington III protected: 114cc6b12beSWilliam A. Kennington III Event event; 115cc6b12beSWilliam A. Kennington III internal::SdRef<sd_event_source> source; 1160a816c5dSWilliam A. Kennington III 117*bc4e4569SWilliam A. Kennington III /** @brief Constructs a basic event source wrapper 118*bc4e4569SWilliam A. Kennington III * Adds a reference to the source 119*bc4e4569SWilliam A. Kennington III * 120*bc4e4569SWilliam A. Kennington III * @param[in] event - The event associated with the source 121*bc4e4569SWilliam A. Kennington III * @param[in] source - The underlying sd_event_source wrapped 122*bc4e4569SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 123*bc4e4569SWilliam A. Kennington III */ 124715c72f8SWilliam A. Kennington III Base(const Event& event, sd_event_source* source); 125*bc4e4569SWilliam A. Kennington III 126*bc4e4569SWilliam A. Kennington III /** @brief Constructs a basic event source wrapper 127*bc4e4569SWilliam A. Kennington III * Owns the passed reference to the source 128*bc4e4569SWilliam A. Kennington III * This ownership is exception safe and will properly free the 129*bc4e4569SWilliam A. Kennington III * source in the case of an exception during construction 130*bc4e4569SWilliam A. Kennington III * 131*bc4e4569SWilliam A. Kennington III * @param[in] event - The event associated with the source 132*bc4e4569SWilliam A. Kennington III * @param[in] source - The underlying sd_event_source wrapped 133*bc4e4569SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 134*bc4e4569SWilliam A. Kennington III */ 135715c72f8SWilliam A. Kennington III Base(const Event& event, sd_event_source* source, std::false_type); 13648c42751SWilliam A. Kennington III 137cc6b12beSWilliam A. Kennington III // We can't ever copy an event_source because the callback 138cc6b12beSWilliam A. Kennington III // data has to be unique. 139cc6b12beSWilliam A. Kennington III Base(const Base& other) = delete; 140cc6b12beSWilliam A. Kennington III Base& operator=(const Base& other) = delete; 141cc6b12beSWilliam A. Kennington III // We don't want to allow any kind of slicing. 1422d943eadSWilliam A. Kennington III Base(Base&& other); 143cc6b12beSWilliam A. Kennington III Base& operator=(Base&& other); 144cc6b12beSWilliam A. Kennington III 145*bc4e4569SWilliam A. Kennington III /** @brief Returns a reference to the prepare callback executed for this 146*bc4e4569SWilliam A. Kennington III * source 147*bc4e4569SWilliam A. Kennington III * 148*bc4e4569SWilliam A. Kennington III * @return A reference to the callback, this should be checked to make sure 149*bc4e4569SWilliam A. Kennington III * the callback is valid as there is no guarantee 150*bc4e4569SWilliam A. Kennington III */ 151e0f1d199SWilliam A. Kennington III const Callback& get_prepare() const; 152e0f1d199SWilliam A. Kennington III 153*bc4e4569SWilliam A. Kennington III /** @brief A helper for subclasses to trivially wrap a c++ style callback 154*bc4e4569SWilliam A. Kennington III * to be called from the sd-event c library 155*bc4e4569SWilliam A. Kennington III * 156*bc4e4569SWilliam A. Kennington III * @param[in] name - The name of the callback for use in error messages 157*bc4e4569SWilliam A. Kennington III * @param[in] source - The sd_event_source provided by sd-event 158*bc4e4569SWilliam A. Kennington III * @param[in] userdata - The userdata provided by sd-event 159*bc4e4569SWilliam A. Kennington III * @param[in] args... - Extra arguments to pass to the callaback 160*bc4e4569SWilliam A. Kennington III * @return An negative errno on error, or 0 on success 161*bc4e4569SWilliam A. Kennington III */ 162e0f1d199SWilliam A. Kennington III template <typename Callback, class Source, 163e0f1d199SWilliam A. Kennington III const Callback& (Source::*getter)() const, typename... Args> 164e0f1d199SWilliam A. Kennington III static int sourceCallback(const char* name, sd_event_source*, 165e0f1d199SWilliam A. Kennington III void* userdata, Args... args) 166e0f1d199SWilliam A. Kennington III { 167e0f1d199SWilliam A. Kennington III if (userdata == nullptr) 168e0f1d199SWilliam A. Kennington III { 169e0f1d199SWilliam A. Kennington III fprintf(stderr, "sdeventplus: %s: Missing userdata\n", name); 170e0f1d199SWilliam A. Kennington III return -EINVAL; 171e0f1d199SWilliam A. Kennington III } 172e0f1d199SWilliam A. Kennington III Source* source = reinterpret_cast<Source*>(userdata); 173e0f1d199SWilliam A. Kennington III return internal::performCallback(name, (source->*getter)(), 174e0f1d199SWilliam A. Kennington III std::ref(*source), args...); 175e0f1d199SWilliam A. Kennington III } 176e0f1d199SWilliam A. Kennington III 17748c42751SWilliam A. Kennington III private: 17848c42751SWilliam A. Kennington III Callback prepare; 1792d943eadSWilliam A. Kennington III 180*bc4e4569SWilliam A. Kennington III /** @brief A helper used to make sure the userdata for the sd-event 181*bc4e4569SWilliam A. Kennington III * callback is set to the current source c++ object 182*bc4e4569SWilliam A. Kennington III * 183*bc4e4569SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 184*bc4e4569SWilliam A. Kennington III */ 1852d943eadSWilliam A. Kennington III void set_userdata(); 186*bc4e4569SWilliam A. Kennington III 187*bc4e4569SWilliam A. Kennington III /** @brief A wrapper around the callback that can be called from sd-event 188*bc4e4569SWilliam A. Kennington III * 189*bc4e4569SWilliam A. Kennington III * @param[in] source - The sd_event_source associated with the call 190*bc4e4569SWilliam A. Kennington III * @param[in] userdata - The provided userdata for the source 191*bc4e4569SWilliam A. Kennington III * @return 0 on success or a negative errno otherwise 192*bc4e4569SWilliam A. Kennington III */ 193e0f1d199SWilliam A. Kennington III static int prepareCallback(sd_event_source* source, void* userdata); 1940a816c5dSWilliam A. Kennington III }; 1950a816c5dSWilliam A. Kennington III 1960a816c5dSWilliam A. Kennington III } // namespace source 1970a816c5dSWilliam A. Kennington III } // namespace sdeventplus 198