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> 85320b1f5SWilliam A. Kennington III #include <memory> 9715c72f8SWilliam A. Kennington III #include <sdeventplus/event.hpp> 105320b1f5SWilliam A. Kennington III #include <sdeventplus/types.hpp> 1156dc78baSWilliam A. Kennington III #include <stdplus/handle/copyable.hpp> 120a816c5dSWilliam A. Kennington III #include <systemd/sd-bus.h> 130a816c5dSWilliam A. Kennington III #include <type_traits> 141e125d97SWilliam A. Kennington III #include <utility> 150a816c5dSWilliam A. Kennington III 160a816c5dSWilliam A. Kennington III namespace sdeventplus 170a816c5dSWilliam A. Kennington III { 180a816c5dSWilliam A. Kennington III namespace source 190a816c5dSWilliam A. Kennington III { 200a816c5dSWilliam A. Kennington III 218fd0cd4cSWilliam A. Kennington III /** @class Enabled 228fd0cd4cSWilliam A. Kennington III * @brief Mapping of sdeventplus source enable values to the sd-event 238fd0cd4cSWilliam A. Kennington III * equivalent 248fd0cd4cSWilliam A. Kennington III */ 258fd0cd4cSWilliam A. Kennington III enum class Enabled 268fd0cd4cSWilliam A. Kennington III { 278fd0cd4cSWilliam A. Kennington III Off = SD_EVENT_OFF, 288fd0cd4cSWilliam A. Kennington III On = SD_EVENT_ON, 298fd0cd4cSWilliam A. Kennington III OneShot = SD_EVENT_ONESHOT, 308fd0cd4cSWilliam A. Kennington III }; 318fd0cd4cSWilliam A. Kennington III 325320b1f5SWilliam A. Kennington III namespace detail 335320b1f5SWilliam A. Kennington III { 345320b1f5SWilliam A. Kennington III class BaseData; 355320b1f5SWilliam A. Kennington III } // namespace detail 365320b1f5SWilliam A. Kennington III 373c845caaSWilliam A. Kennington III /** @class Base 383c845caaSWilliam A. Kennington III * @brief The base class for all sources implementing common source methods 393c845caaSWilliam A. Kennington III * Not instantiated directly by end users 403c845caaSWilliam A. Kennington III */ 410a816c5dSWilliam A. Kennington III class Base 420a816c5dSWilliam A. Kennington III { 430a816c5dSWilliam A. Kennington III public: 44220b5dabSWilliam A. Kennington III using Callback = fu2::unique_function<void(Base& source)>; 4548c42751SWilliam A. Kennington III 465320b1f5SWilliam A. Kennington III Base(Base&& other) = default; 475320b1f5SWilliam A. Kennington III Base& operator=(Base&& other) = default; 4856dc78baSWilliam A. Kennington III Base(const Base& other) = default; 4956dc78baSWilliam A. Kennington III Base& operator=(const Base& other) = default; 505320b1f5SWilliam A. Kennington III virtual ~Base() = default; 5165db863eSWilliam A. Kennington III 523c845caaSWilliam A. Kennington III /** @brief Gets the underlying sd_event_source 533c845caaSWilliam A. Kennington III * 543c845caaSWilliam A. Kennington III * @return The sd_event_source 553c845caaSWilliam A. Kennington III */ 564863b96bSWilliam A. Kennington III sd_event_source* get() const; 573c845caaSWilliam A. Kennington III 583c845caaSWilliam A. Kennington III /** @brief Gets the associated Event object 593c845caaSWilliam A. Kennington III * 603c845caaSWilliam A. Kennington III * @return The Event 613c845caaSWilliam A. Kennington III */ 62715c72f8SWilliam A. Kennington III const Event& get_event() const; 63715c72f8SWilliam A. Kennington III 643c845caaSWilliam A. Kennington III /** @brief Gets the description of the source 653c845caaSWilliam A. Kennington III * 663c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 673c845caaSWilliam A. Kennington III * @return The c-string description or a nullptr if none exists 683c845caaSWilliam A. Kennington III */ 69d9fd9815SWilliam A. Kennington III const char* get_description() const; 703c845caaSWilliam A. Kennington III 713c845caaSWilliam A. Kennington III /** @brief Sets the description of the source 723c845caaSWilliam A. Kennington III * 733c845caaSWilliam A. Kennington III * @param[in] description - The c-string description 743c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 753c845caaSWilliam A. Kennington III */ 76d9fd9815SWilliam A. Kennington III void set_description(const char* description) const; 773c845caaSWilliam A. Kennington III 783c845caaSWilliam A. Kennington III /** @brief Sets the callback associated with the source to be performed 793c845caaSWilliam A. Kennington III * before the event loop goes to sleep, waiting for new events 803c845caaSWilliam A. Kennington III * 813c845caaSWilliam A. Kennington III * @param[in] callback - Function run for preparation of the source 823c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 833c845caaSWilliam A. Kennington III */ 8448c42751SWilliam A. Kennington III void set_prepare(Callback&& callback); 853c845caaSWilliam A. Kennington III 863c845caaSWilliam A. Kennington III /** @brief Whether or not the source has any pending events that have 873c845caaSWilliam A. Kennington III * not been dispatched yet. 883c845caaSWilliam A. Kennington III * 893c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 903c845caaSWilliam A. Kennington III * @return 'true' if the source has pending events 913c845caaSWilliam A. Kennington III * 'false' otherwise 923c845caaSWilliam A. Kennington III */ 938fd0cd4cSWilliam A. Kennington III bool get_pending() const; 943c845caaSWilliam A. Kennington III 953c845caaSWilliam A. Kennington III /** @brief Gets the priority of the source relative to other sources 963c845caaSWilliam A. Kennington III * The lower the priority the more important the source 973c845caaSWilliam A. Kennington III * 983c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 993c845caaSWilliam A. Kennington III * @return A 64 bit integer representing the dispatch priority 1003c845caaSWilliam A. Kennington III */ 101d9fd9815SWilliam A. Kennington III int64_t get_priority() const; 1023c845caaSWilliam A. Kennington III 1033c845caaSWilliam A. Kennington III /** @brief Sets the priority of the source relative to other sources 1043c845caaSWilliam A. Kennington III * The lower the priority the more important the source 1053c845caaSWilliam A. Kennington III * 1063c845caaSWilliam A. Kennington III * @param[in] priority - A 64 bit integer representing the priority 1073c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1083c845caaSWilliam A. Kennington III */ 109d9fd9815SWilliam A. Kennington III void set_priority(int64_t priority) const; 1103c845caaSWilliam A. Kennington III 1113c845caaSWilliam A. Kennington III /** @brief Determines the enablement value of the source 1123c845caaSWilliam A. Kennington III * 1133c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1143c845caaSWilliam A. Kennington III * @return The enabled status of the source 1153c845caaSWilliam A. Kennington III */ 1168fd0cd4cSWilliam A. Kennington III Enabled get_enabled() const; 1173c845caaSWilliam A. Kennington III 1183c845caaSWilliam A. Kennington III /** @brief Sets the enablement value of the source 1193c845caaSWilliam A. Kennington III * 1203c845caaSWilliam A. Kennington III * @param[in] enabled - The new state of the source 1213c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1223c845caaSWilliam A. Kennington III */ 1238fd0cd4cSWilliam A. Kennington III void set_enabled(Enabled enabled) const; 12465db863eSWilliam A. Kennington III 12543493b58SWilliam A. Kennington III /** @brief Determines the floating nature of the source 12643493b58SWilliam A. Kennington III * 12743493b58SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 12843493b58SWilliam A. Kennington III * @return The enabled status of the source 12943493b58SWilliam A. Kennington III */ 13043493b58SWilliam A. Kennington III bool get_floating() const; 13143493b58SWilliam A. Kennington III 13243493b58SWilliam A. Kennington III /** @brief Sets the floating nature of the source 13343493b58SWilliam A. Kennington III * If set to true, the source will continue to run after the 13443493b58SWilliam A. Kennington III * destruction of this handle. 13543493b58SWilliam A. Kennington III * 13643493b58SWilliam A. Kennington III * @param[in] b - Whether or not the source should float 13743493b58SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 13843493b58SWilliam A. Kennington III */ 13943493b58SWilliam A. Kennington III void set_floating(bool b) const; 14043493b58SWilliam A. Kennington III 1410a816c5dSWilliam A. Kennington III protected: 142cc6b12beSWilliam A. Kennington III Event event; 1430a816c5dSWilliam A. Kennington III 144bc4e4569SWilliam A. Kennington III /** @brief Constructs a basic event source wrapper 145bc4e4569SWilliam A. Kennington III * Owns the passed reference to the source 146bc4e4569SWilliam A. Kennington III * This ownership is exception safe and will properly free the 147bc4e4569SWilliam A. Kennington III * source in the case of an exception during construction 148bc4e4569SWilliam A. Kennington III * 149bc4e4569SWilliam A. Kennington III * @param[in] event - The event associated with the source 150bc4e4569SWilliam A. Kennington III * @param[in] source - The underlying sd_event_source wrapped 1512301d47fSWilliam A. Kennington III * @param[in] - Signifies that ownership is being transfered 152bc4e4569SWilliam A. Kennington III */ 153715c72f8SWilliam A. Kennington III Base(const Event& event, sd_event_source* source, std::false_type); 15448c42751SWilliam A. Kennington III 1555320b1f5SWilliam A. Kennington III /** @brief Constructs a basic non-owning event source wrapper 1565320b1f5SWilliam A. Kennington III * Does not own the passed reference to the source because 1575320b1f5SWilliam A. Kennington III * this is meant to be used only as a reference inside an event 1585320b1f5SWilliam A. Kennington III * source. 1595320b1f5SWilliam A. Kennington III * @internal 1605320b1f5SWilliam A. Kennington III * 1615320b1f5SWilliam A. Kennington III * @param[in] other - The source wrapper to copy 1625320b1f5SWilliam A. Kennington III * @param[in] - Signifies that this new copy is non-owning 1635320b1f5SWilliam A. Kennington III */ 1645320b1f5SWilliam A. Kennington III Base(const Base& other, sdeventplus::internal::NoOwn); 1655320b1f5SWilliam A. Kennington III 1665320b1f5SWilliam A. Kennington III /** @brief Sets the userdata of the source to the passed in source 1675320b1f5SWilliam A. Kennington III * This needs to be called by all source implementors. 1685320b1f5SWilliam A. Kennington III * 1695320b1f5SWilliam A. Kennington III * @param[in] data - The data stored in the userdata slot. 1705320b1f5SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1715320b1f5SWilliam A. Kennington III */ 1725320b1f5SWilliam A. Kennington III void set_userdata(std::unique_ptr<detail::BaseData> data) const; 1735320b1f5SWilliam A. Kennington III 1745320b1f5SWilliam A. Kennington III /** @brief Get the heap allocated version of the Base 1755320b1f5SWilliam A. Kennington III * 1765320b1f5SWilliam A. Kennington III * @return A reference to the Base 1775320b1f5SWilliam A. Kennington III */ 1785320b1f5SWilliam A. Kennington III detail::BaseData& get_userdata() const; 179cc6b12beSWilliam A. Kennington III 180bc4e4569SWilliam A. Kennington III /** @brief Returns a reference to the prepare callback executed for this 181bc4e4569SWilliam A. Kennington III * source 182bc4e4569SWilliam A. Kennington III * 183bc4e4569SWilliam A. Kennington III * @return A reference to the callback, this should be checked to make sure 184bc4e4569SWilliam A. Kennington III * the callback is valid as there is no guarantee 185bc4e4569SWilliam A. Kennington III */ 186220b5dabSWilliam A. Kennington III Callback& get_prepare(); 187e0f1d199SWilliam A. Kennington III 188bc4e4569SWilliam A. Kennington III /** @brief A helper for subclasses to trivially wrap a c++ style callback 189bc4e4569SWilliam A. Kennington III * to be called from the sd-event c library 190bc4e4569SWilliam A. Kennington III * 191bc4e4569SWilliam A. Kennington III * @param[in] name - The name of the callback for use in error messages 192bc4e4569SWilliam A. Kennington III * @param[in] source - The sd_event_source provided by sd-event 193bc4e4569SWilliam A. Kennington III * @param[in] userdata - The userdata provided by sd-event 194bc4e4569SWilliam A. Kennington III * @param[in] args... - Extra arguments to pass to the callaback 195bc4e4569SWilliam A. Kennington III * @return An negative errno on error, or 0 on success 196bc4e4569SWilliam A. Kennington III */ 1975320b1f5SWilliam A. Kennington III template <typename Callback, class Data, auto getter, typename... Args> 198e0f1d199SWilliam A. Kennington III static int sourceCallback(const char* name, sd_event_source*, 1991e125d97SWilliam A. Kennington III void* userdata, Args&&... args) 200e0f1d199SWilliam A. Kennington III { 201e0f1d199SWilliam A. Kennington III if (userdata == nullptr) 202e0f1d199SWilliam A. Kennington III { 203e0f1d199SWilliam A. Kennington III fprintf(stderr, "sdeventplus: %s: Missing userdata\n", name); 204e0f1d199SWilliam A. Kennington III return -EINVAL; 205e0f1d199SWilliam A. Kennington III } 2065320b1f5SWilliam A. Kennington III Data& data = 2075320b1f5SWilliam A. Kennington III static_cast<Data&>(*reinterpret_cast<detail::BaseData*>(userdata)); 2085320b1f5SWilliam A. Kennington III Callback& callback = std::invoke(getter, data); 209*8e7ec0feSWilliam A. Kennington III try 210*8e7ec0feSWilliam A. Kennington III { 211*8e7ec0feSWilliam A. Kennington III std::invoke(callback, data, std::forward<Args>(args)...); 212*8e7ec0feSWilliam A. Kennington III } 213*8e7ec0feSWilliam A. Kennington III catch (const std::exception& e) 214*8e7ec0feSWilliam A. Kennington III { 215*8e7ec0feSWilliam A. Kennington III fprintf(stderr, "sdeventplus: %s: %s\n", name, e.what()); 216*8e7ec0feSWilliam A. Kennington III } 217*8e7ec0feSWilliam A. Kennington III catch (...) 218*8e7ec0feSWilliam A. Kennington III { 219*8e7ec0feSWilliam A. Kennington III fprintf(stderr, "sdeventplus: %s: Unknown error\n", name); 220*8e7ec0feSWilliam A. Kennington III } 221*8e7ec0feSWilliam A. Kennington III return 0; 222e0f1d199SWilliam A. Kennington III } 223e0f1d199SWilliam A. Kennington III 22448c42751SWilliam A. Kennington III private: 22556dc78baSWilliam A. Kennington III static sd_event_source* ref(sd_event_source* const& source, 22656dc78baSWilliam A. Kennington III const internal::SdEvent*& sdevent, bool& owned); 227e04cb03bSWilliam A. Kennington III static void drop(sd_event_source*&& source, 2285320b1f5SWilliam A. Kennington III const internal::SdEvent*& sdevent, bool& owned); 229e04cb03bSWilliam A. Kennington III 23056dc78baSWilliam A. Kennington III stdplus::Copyable<sd_event_source*, const internal::SdEvent*, 23156dc78baSWilliam A. Kennington III bool>::Handle<drop, ref> 232e04cb03bSWilliam A. Kennington III source; 2332d943eadSWilliam A. Kennington III 2345320b1f5SWilliam A. Kennington III /** @brief A wrapper around deleting the heap allocated base class 2355320b1f5SWilliam A. Kennington III * This is needed for calls from sd_event destroy callbacks. 236bc4e4569SWilliam A. Kennington III * 2375320b1f5SWilliam A. Kennington III * @param[in] userdata - The provided userdata for the source 238bc4e4569SWilliam A. Kennington III */ 2395320b1f5SWilliam A. Kennington III static void destroy_userdata(void* userdata); 240bc4e4569SWilliam A. Kennington III 241bc4e4569SWilliam A. Kennington III /** @brief A wrapper around the callback that can be called from sd-event 242bc4e4569SWilliam A. Kennington III * 243bc4e4569SWilliam A. Kennington III * @param[in] source - The sd_event_source associated with the call 244bc4e4569SWilliam A. Kennington III * @param[in] userdata - The provided userdata for the source 245bc4e4569SWilliam A. Kennington III * @return 0 on success or a negative errno otherwise 246bc4e4569SWilliam A. Kennington III */ 247e0f1d199SWilliam A. Kennington III static int prepareCallback(sd_event_source* source, void* userdata); 2480a816c5dSWilliam A. Kennington III }; 2490a816c5dSWilliam A. Kennington III 2505320b1f5SWilliam A. Kennington III namespace detail 2515320b1f5SWilliam A. Kennington III { 2525320b1f5SWilliam A. Kennington III 2535320b1f5SWilliam A. Kennington III class BaseData : public Base 2545320b1f5SWilliam A. Kennington III { 2555320b1f5SWilliam A. Kennington III private: 2565320b1f5SWilliam A. Kennington III Base::Callback prepare; 2575320b1f5SWilliam A. Kennington III 2585320b1f5SWilliam A. Kennington III public: 2595320b1f5SWilliam A. Kennington III BaseData(const Base& base); 2605320b1f5SWilliam A. Kennington III 2615320b1f5SWilliam A. Kennington III friend Base; 2625320b1f5SWilliam A. Kennington III }; 2635320b1f5SWilliam A. Kennington III 2645320b1f5SWilliam A. Kennington III } // namespace detail 2655320b1f5SWilliam A. Kennington III 2660a816c5dSWilliam A. Kennington III } // namespace source 2670a816c5dSWilliam A. Kennington III } // namespace sdeventplus 268