10a816c5dSWilliam A. Kennington III #pragma once 20a816c5dSWilliam A. Kennington III 3*a8c11e3cSPatrick Williams #include <systemd/sd-bus.h> 4*a8c11e3cSPatrick Williams 5220b5dabSWilliam A. Kennington III #include <function2/function2.hpp> 6715c72f8SWilliam A. Kennington III #include <sdeventplus/event.hpp> 75320b1f5SWilliam A. Kennington III #include <sdeventplus/types.hpp> 856dc78baSWilliam A. Kennington III #include <stdplus/handle/copyable.hpp> 9*a8c11e3cSPatrick Williams 10*a8c11e3cSPatrick Williams #include <cerrno> 11*a8c11e3cSPatrick Williams #include <cstdint> 12*a8c11e3cSPatrick Williams #include <cstdio> 13*a8c11e3cSPatrick Williams #include <functional> 14*a8c11e3cSPatrick Williams #include <memory> 150a816c5dSWilliam A. Kennington III #include <type_traits> 161e125d97SWilliam A. Kennington III #include <utility> 170a816c5dSWilliam A. Kennington III 180a816c5dSWilliam A. Kennington III namespace sdeventplus 190a816c5dSWilliam A. Kennington III { 200a816c5dSWilliam A. Kennington III namespace source 210a816c5dSWilliam A. Kennington III { 220a816c5dSWilliam A. Kennington III 238fd0cd4cSWilliam A. Kennington III /** @class Enabled 248fd0cd4cSWilliam A. Kennington III * @brief Mapping of sdeventplus source enable values to the sd-event 258fd0cd4cSWilliam A. Kennington III * equivalent 268fd0cd4cSWilliam A. Kennington III */ 278fd0cd4cSWilliam A. Kennington III enum class Enabled 288fd0cd4cSWilliam A. Kennington III { 298fd0cd4cSWilliam A. Kennington III Off = SD_EVENT_OFF, 308fd0cd4cSWilliam A. Kennington III On = SD_EVENT_ON, 318fd0cd4cSWilliam A. Kennington III OneShot = SD_EVENT_ONESHOT, 328fd0cd4cSWilliam A. Kennington III }; 338fd0cd4cSWilliam A. Kennington III 345320b1f5SWilliam A. Kennington III namespace detail 355320b1f5SWilliam A. Kennington III { 365320b1f5SWilliam A. Kennington III class BaseData; 375320b1f5SWilliam A. Kennington III } // namespace detail 385320b1f5SWilliam A. Kennington III 393c845caaSWilliam A. Kennington III /** @class Base 403c845caaSWilliam A. Kennington III * @brief The base class for all sources implementing common source methods 413c845caaSWilliam A. Kennington III * Not instantiated directly by end users 423c845caaSWilliam A. Kennington III */ 430a816c5dSWilliam A. Kennington III class Base 440a816c5dSWilliam A. Kennington III { 450a816c5dSWilliam A. Kennington III public: 46220b5dabSWilliam A. Kennington III using Callback = fu2::unique_function<void(Base& source)>; 4748c42751SWilliam A. Kennington III 485320b1f5SWilliam A. Kennington III Base(Base&& other) = default; 495320b1f5SWilliam A. Kennington III Base& operator=(Base&& other) = default; 5056dc78baSWilliam A. Kennington III Base(const Base& other) = default; 5156dc78baSWilliam A. Kennington III Base& operator=(const Base& other) = default; 525320b1f5SWilliam A. Kennington III virtual ~Base() = default; 5365db863eSWilliam A. Kennington III 543c845caaSWilliam A. Kennington III /** @brief Gets the underlying sd_event_source 553c845caaSWilliam A. Kennington III * 563c845caaSWilliam A. Kennington III * @return The sd_event_source 573c845caaSWilliam A. Kennington III */ 584863b96bSWilliam A. Kennington III sd_event_source* get() const; 593c845caaSWilliam A. Kennington III 603c845caaSWilliam A. Kennington III /** @brief Gets the associated Event object 613c845caaSWilliam A. Kennington III * 623c845caaSWilliam A. Kennington III * @return The Event 633c845caaSWilliam A. Kennington III */ 64715c72f8SWilliam A. Kennington III const Event& get_event() const; 65715c72f8SWilliam A. Kennington III 663c845caaSWilliam A. Kennington III /** @brief Gets the description of the source 673c845caaSWilliam A. Kennington III * 683c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 693c845caaSWilliam A. Kennington III * @return The c-string description or a nullptr if none exists 703c845caaSWilliam A. Kennington III */ 71d9fd9815SWilliam A. Kennington III const char* get_description() const; 723c845caaSWilliam A. Kennington III 733c845caaSWilliam A. Kennington III /** @brief Sets the description of the source 743c845caaSWilliam A. Kennington III * 753c845caaSWilliam A. Kennington III * @param[in] description - The c-string description 763c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 773c845caaSWilliam A. Kennington III */ 78d9fd9815SWilliam A. Kennington III void set_description(const char* description) const; 793c845caaSWilliam A. Kennington III 803c845caaSWilliam A. Kennington III /** @brief Sets the callback associated with the source to be performed 813c845caaSWilliam A. Kennington III * before the event loop goes to sleep, waiting for new events 823c845caaSWilliam A. Kennington III * 833c845caaSWilliam A. Kennington III * @param[in] callback - Function run for preparation of the source 843c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 853c845caaSWilliam A. Kennington III */ 8648c42751SWilliam A. Kennington III void set_prepare(Callback&& callback); 873c845caaSWilliam A. Kennington III 883c845caaSWilliam A. Kennington III /** @brief Whether or not the source has any pending events that have 893c845caaSWilliam A. Kennington III * not been dispatched yet. 903c845caaSWilliam A. Kennington III * 913c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 923c845caaSWilliam A. Kennington III * @return 'true' if the source has pending events 933c845caaSWilliam A. Kennington III * 'false' otherwise 943c845caaSWilliam A. Kennington III */ 958fd0cd4cSWilliam A. Kennington III bool get_pending() const; 963c845caaSWilliam A. Kennington III 973c845caaSWilliam A. Kennington III /** @brief Gets the priority of the source relative to other sources 983c845caaSWilliam A. Kennington III * The lower the priority the more important the source 993c845caaSWilliam A. Kennington III * 1003c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1013c845caaSWilliam A. Kennington III * @return A 64 bit integer representing the dispatch priority 1023c845caaSWilliam A. Kennington III */ 103d9fd9815SWilliam A. Kennington III int64_t get_priority() const; 1043c845caaSWilliam A. Kennington III 1053c845caaSWilliam A. Kennington III /** @brief Sets the priority of the source relative to other sources 1063c845caaSWilliam A. Kennington III * The lower the priority the more important the source 1073c845caaSWilliam A. Kennington III * 1083c845caaSWilliam A. Kennington III * @param[in] priority - A 64 bit integer representing the priority 1093c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1103c845caaSWilliam A. Kennington III */ 111d9fd9815SWilliam A. Kennington III void set_priority(int64_t priority) const; 1123c845caaSWilliam A. Kennington III 1133c845caaSWilliam A. Kennington III /** @brief Determines the enablement value of the source 1143c845caaSWilliam A. Kennington III * 1153c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1163c845caaSWilliam A. Kennington III * @return The enabled status of the source 1173c845caaSWilliam A. Kennington III */ 1188fd0cd4cSWilliam A. Kennington III Enabled get_enabled() const; 1193c845caaSWilliam A. Kennington III 1203c845caaSWilliam A. Kennington III /** @brief Sets the enablement value of the source 1213c845caaSWilliam A. Kennington III * 1223c845caaSWilliam A. Kennington III * @param[in] enabled - The new state of the source 1233c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1243c845caaSWilliam A. Kennington III */ 1258fd0cd4cSWilliam A. Kennington III void set_enabled(Enabled enabled) const; 12665db863eSWilliam A. Kennington III 12743493b58SWilliam A. Kennington III /** @brief Determines the floating nature of the source 12843493b58SWilliam A. Kennington III * 12943493b58SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 13043493b58SWilliam A. Kennington III * @return The enabled status of the source 13143493b58SWilliam A. Kennington III */ 13243493b58SWilliam A. Kennington III bool get_floating() const; 13343493b58SWilliam A. Kennington III 13443493b58SWilliam A. Kennington III /** @brief Sets the floating nature of the source 13543493b58SWilliam A. Kennington III * If set to true, the source will continue to run after the 13643493b58SWilliam A. Kennington III * destruction of this handle. 13743493b58SWilliam A. Kennington III * 13843493b58SWilliam A. Kennington III * @param[in] b - Whether or not the source should float 13943493b58SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 14043493b58SWilliam A. Kennington III */ 14143493b58SWilliam A. Kennington III void set_floating(bool b) const; 14243493b58SWilliam A. Kennington III 1430a816c5dSWilliam A. Kennington III protected: 144cc6b12beSWilliam A. Kennington III Event event; 1450a816c5dSWilliam A. Kennington III 146bc4e4569SWilliam A. Kennington III /** @brief Constructs a basic event source wrapper 147bc4e4569SWilliam A. Kennington III * Owns the passed reference to the source 148bc4e4569SWilliam A. Kennington III * This ownership is exception safe and will properly free the 149bc4e4569SWilliam A. Kennington III * source in the case of an exception during construction 150bc4e4569SWilliam A. Kennington III * 151bc4e4569SWilliam A. Kennington III * @param[in] event - The event associated with the source 152bc4e4569SWilliam A. Kennington III * @param[in] source - The underlying sd_event_source wrapped 1532301d47fSWilliam A. Kennington III * @param[in] - Signifies that ownership is being transfered 154bc4e4569SWilliam A. Kennington III */ 155715c72f8SWilliam A. Kennington III Base(const Event& event, sd_event_source* source, std::false_type); 15648c42751SWilliam A. Kennington III 1575320b1f5SWilliam A. Kennington III /** @brief Constructs a basic non-owning event source wrapper 1585320b1f5SWilliam A. Kennington III * Does not own the passed reference to the source because 1595320b1f5SWilliam A. Kennington III * this is meant to be used only as a reference inside an event 1605320b1f5SWilliam A. Kennington III * source. 1615320b1f5SWilliam A. Kennington III * @internal 1625320b1f5SWilliam A. Kennington III * 1635320b1f5SWilliam A. Kennington III * @param[in] other - The source wrapper to copy 1645320b1f5SWilliam A. Kennington III * @param[in] - Signifies that this new copy is non-owning 1655320b1f5SWilliam A. Kennington III */ 1665320b1f5SWilliam A. Kennington III Base(const Base& other, sdeventplus::internal::NoOwn); 1675320b1f5SWilliam A. Kennington III 1685320b1f5SWilliam A. Kennington III /** @brief Sets the userdata of the source to the passed in source 1695320b1f5SWilliam A. Kennington III * This needs to be called by all source implementors. 1705320b1f5SWilliam A. Kennington III * 1715320b1f5SWilliam A. Kennington III * @param[in] data - The data stored in the userdata slot. 1725320b1f5SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1735320b1f5SWilliam A. Kennington III */ 1745320b1f5SWilliam A. Kennington III void set_userdata(std::unique_ptr<detail::BaseData> data) const; 1755320b1f5SWilliam A. Kennington III 1765320b1f5SWilliam A. Kennington III /** @brief Get the heap allocated version of the Base 1775320b1f5SWilliam A. Kennington III * 1785320b1f5SWilliam A. Kennington III * @return A reference to the Base 1795320b1f5SWilliam A. Kennington III */ 1805320b1f5SWilliam A. Kennington III detail::BaseData& get_userdata() const; 181cc6b12beSWilliam A. Kennington III 182bc4e4569SWilliam A. Kennington III /** @brief Returns a reference to the prepare callback executed for this 183bc4e4569SWilliam A. Kennington III * source 184bc4e4569SWilliam A. Kennington III * 185bc4e4569SWilliam A. Kennington III * @return A reference to the callback, this should be checked to make sure 186bc4e4569SWilliam A. Kennington III * the callback is valid as there is no guarantee 187bc4e4569SWilliam A. Kennington III */ 188220b5dabSWilliam A. Kennington III Callback& get_prepare(); 189e0f1d199SWilliam A. Kennington III 190bc4e4569SWilliam A. Kennington III /** @brief A helper for subclasses to trivially wrap a c++ style callback 191bc4e4569SWilliam A. Kennington III * to be called from the sd-event c library 192bc4e4569SWilliam A. Kennington III * 193bc4e4569SWilliam A. Kennington III * @param[in] name - The name of the callback for use in error messages 194bc4e4569SWilliam A. Kennington III * @param[in] source - The sd_event_source provided by sd-event 195bc4e4569SWilliam A. Kennington III * @param[in] userdata - The userdata provided by sd-event 196bc4e4569SWilliam A. Kennington III * @param[in] args... - Extra arguments to pass to the callaback 197bc4e4569SWilliam A. Kennington III * @return An negative errno on error, or 0 on success 198bc4e4569SWilliam A. Kennington III */ 1995320b1f5SWilliam A. Kennington III template <typename Callback, class Data, auto getter, typename... Args> 200e0f1d199SWilliam A. Kennington III static int sourceCallback(const char* name, sd_event_source*, 2011e125d97SWilliam A. Kennington III void* userdata, Args&&... args) 202e0f1d199SWilliam A. Kennington III { 203e0f1d199SWilliam A. Kennington III if (userdata == nullptr) 204e0f1d199SWilliam A. Kennington III { 205e0f1d199SWilliam A. Kennington III fprintf(stderr, "sdeventplus: %s: Missing userdata\n", name); 206e0f1d199SWilliam A. Kennington III return -EINVAL; 207e0f1d199SWilliam A. Kennington III } 2085320b1f5SWilliam A. Kennington III Data& data = 2095320b1f5SWilliam A. Kennington III static_cast<Data&>(*reinterpret_cast<detail::BaseData*>(userdata)); 2105320b1f5SWilliam A. Kennington III Callback& callback = std::invoke(getter, data); 2118e7ec0feSWilliam A. Kennington III try 2128e7ec0feSWilliam A. Kennington III { 2138e7ec0feSWilliam A. Kennington III std::invoke(callback, data, std::forward<Args>(args)...); 2148e7ec0feSWilliam A. Kennington III } 2158e7ec0feSWilliam A. Kennington III catch (const std::exception& e) 2168e7ec0feSWilliam A. Kennington III { 2178e7ec0feSWilliam A. Kennington III fprintf(stderr, "sdeventplus: %s: %s\n", name, e.what()); 2188e7ec0feSWilliam A. Kennington III } 2198e7ec0feSWilliam A. Kennington III catch (...) 2208e7ec0feSWilliam A. Kennington III { 2218e7ec0feSWilliam A. Kennington III fprintf(stderr, "sdeventplus: %s: Unknown error\n", name); 2228e7ec0feSWilliam A. Kennington III } 2238e7ec0feSWilliam A. Kennington III return 0; 224e0f1d199SWilliam A. Kennington III } 225e0f1d199SWilliam A. Kennington III 22648c42751SWilliam A. Kennington III private: 22756dc78baSWilliam A. Kennington III static sd_event_source* ref(sd_event_source* const& source, 22856dc78baSWilliam A. Kennington III const internal::SdEvent*& sdevent, bool& owned); 229e04cb03bSWilliam A. Kennington III static void drop(sd_event_source*&& source, 2305320b1f5SWilliam A. Kennington III const internal::SdEvent*& sdevent, bool& owned); 231e04cb03bSWilliam A. Kennington III 23256dc78baSWilliam A. Kennington III stdplus::Copyable<sd_event_source*, const internal::SdEvent*, 23356dc78baSWilliam A. Kennington III bool>::Handle<drop, ref> 234e04cb03bSWilliam A. Kennington III source; 2352d943eadSWilliam A. Kennington III 2365320b1f5SWilliam A. Kennington III /** @brief A wrapper around deleting the heap allocated base class 2375320b1f5SWilliam A. Kennington III * This is needed for calls from sd_event destroy callbacks. 238bc4e4569SWilliam A. Kennington III * 2395320b1f5SWilliam A. Kennington III * @param[in] userdata - The provided userdata for the source 240bc4e4569SWilliam A. Kennington III */ 2415320b1f5SWilliam A. Kennington III static void destroy_userdata(void* userdata); 242bc4e4569SWilliam A. Kennington III 243bc4e4569SWilliam A. Kennington III /** @brief A wrapper around the callback that can be called from sd-event 244bc4e4569SWilliam A. Kennington III * 245bc4e4569SWilliam A. Kennington III * @param[in] source - The sd_event_source associated with the call 246bc4e4569SWilliam A. Kennington III * @param[in] userdata - The provided userdata for the source 247bc4e4569SWilliam A. Kennington III * @return 0 on success or a negative errno otherwise 248bc4e4569SWilliam A. Kennington III */ 249e0f1d199SWilliam A. Kennington III static int prepareCallback(sd_event_source* source, void* userdata); 2500a816c5dSWilliam A. Kennington III }; 2510a816c5dSWilliam A. Kennington III 2525320b1f5SWilliam A. Kennington III namespace detail 2535320b1f5SWilliam A. Kennington III { 2545320b1f5SWilliam A. Kennington III 2555320b1f5SWilliam A. Kennington III class BaseData : public Base 2565320b1f5SWilliam A. Kennington III { 2575320b1f5SWilliam A. Kennington III private: 2585320b1f5SWilliam A. Kennington III Base::Callback prepare; 2595320b1f5SWilliam A. Kennington III 2605320b1f5SWilliam A. Kennington III public: 2615320b1f5SWilliam A. Kennington III BaseData(const Base& base); 2625320b1f5SWilliam A. Kennington III 2635320b1f5SWilliam A. Kennington III friend Base; 2645320b1f5SWilliam A. Kennington III }; 2655320b1f5SWilliam A. Kennington III 2665320b1f5SWilliam A. Kennington III } // namespace detail 2675320b1f5SWilliam A. Kennington III 2680a816c5dSWilliam A. Kennington III } // namespace source 2690a816c5dSWilliam A. Kennington III } // namespace sdeventplus 270