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> 10e0f1d199SWilliam A. Kennington III #include <sdeventplus/internal/utils.hpp> 115320b1f5SWilliam A. Kennington III #include <sdeventplus/types.hpp> 1256dc78baSWilliam A. Kennington III #include <stdplus/handle/copyable.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 335320b1f5SWilliam A. Kennington III namespace detail 345320b1f5SWilliam A. Kennington III { 355320b1f5SWilliam A. Kennington III class BaseData; 365320b1f5SWilliam A. Kennington III } // namespace detail 375320b1f5SWilliam 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 475320b1f5SWilliam A. Kennington III Base(Base&& other) = default; 485320b1f5SWilliam A. Kennington III Base& operator=(Base&& other) = default; 4956dc78baSWilliam A. Kennington III Base(const Base& other) = default; 5056dc78baSWilliam A. Kennington III Base& operator=(const Base& other) = default; 515320b1f5SWilliam A. Kennington III virtual ~Base() = default; 5265db863eSWilliam A. Kennington III 533c845caaSWilliam A. Kennington III /** @brief Gets the underlying sd_event_source 543c845caaSWilliam A. Kennington III * 553c845caaSWilliam A. Kennington III * @return The sd_event_source 563c845caaSWilliam A. Kennington III */ 574863b96bSWilliam A. Kennington III sd_event_source* get() const; 583c845caaSWilliam A. Kennington III 593c845caaSWilliam A. Kennington III /** @brief Gets the associated Event object 603c845caaSWilliam A. Kennington III * 613c845caaSWilliam A. Kennington III * @return The Event 623c845caaSWilliam A. Kennington III */ 63715c72f8SWilliam A. Kennington III const Event& get_event() const; 64715c72f8SWilliam A. Kennington III 653c845caaSWilliam A. Kennington III /** @brief Gets the description of the source 663c845caaSWilliam A. Kennington III * 673c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 683c845caaSWilliam A. Kennington III * @return The c-string description or a nullptr if none exists 693c845caaSWilliam A. Kennington III */ 70d9fd9815SWilliam A. Kennington III const char* get_description() const; 713c845caaSWilliam A. Kennington III 723c845caaSWilliam A. Kennington III /** @brief Sets the description of the source 733c845caaSWilliam A. Kennington III * 743c845caaSWilliam A. Kennington III * @param[in] description - The c-string description 753c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 763c845caaSWilliam A. Kennington III */ 77d9fd9815SWilliam A. Kennington III void set_description(const char* description) const; 783c845caaSWilliam A. Kennington III 793c845caaSWilliam A. Kennington III /** @brief Sets the callback associated with the source to be performed 803c845caaSWilliam A. Kennington III * before the event loop goes to sleep, waiting for new events 813c845caaSWilliam A. Kennington III * 823c845caaSWilliam A. Kennington III * @param[in] callback - Function run for preparation of the source 833c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 843c845caaSWilliam A. Kennington III */ 8548c42751SWilliam A. Kennington III void set_prepare(Callback&& callback); 863c845caaSWilliam A. Kennington III 873c845caaSWilliam A. Kennington III /** @brief Whether or not the source has any pending events that have 883c845caaSWilliam A. Kennington III * not been dispatched yet. 893c845caaSWilliam A. Kennington III * 903c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 913c845caaSWilliam A. Kennington III * @return 'true' if the source has pending events 923c845caaSWilliam A. Kennington III * 'false' otherwise 933c845caaSWilliam A. Kennington III */ 948fd0cd4cSWilliam A. Kennington III bool get_pending() const; 953c845caaSWilliam A. Kennington III 963c845caaSWilliam A. Kennington III /** @brief Gets the priority of the source relative to other sources 973c845caaSWilliam A. Kennington III * The lower the priority the more important the source 983c845caaSWilliam A. Kennington III * 993c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1003c845caaSWilliam A. Kennington III * @return A 64 bit integer representing the dispatch priority 1013c845caaSWilliam A. Kennington III */ 102d9fd9815SWilliam A. Kennington III int64_t get_priority() const; 1033c845caaSWilliam A. Kennington III 1043c845caaSWilliam A. Kennington III /** @brief Sets the priority of the source relative to other sources 1053c845caaSWilliam A. Kennington III * The lower the priority the more important the source 1063c845caaSWilliam A. Kennington III * 1073c845caaSWilliam A. Kennington III * @param[in] priority - A 64 bit integer representing the priority 1083c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1093c845caaSWilliam A. Kennington III */ 110d9fd9815SWilliam A. Kennington III void set_priority(int64_t priority) const; 1113c845caaSWilliam A. Kennington III 1123c845caaSWilliam A. Kennington III /** @brief Determines the enablement value of the source 1133c845caaSWilliam A. Kennington III * 1143c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1153c845caaSWilliam A. Kennington III * @return The enabled status of the source 1163c845caaSWilliam A. Kennington III */ 1178fd0cd4cSWilliam A. Kennington III Enabled get_enabled() const; 1183c845caaSWilliam A. Kennington III 1193c845caaSWilliam A. Kennington III /** @brief Sets the enablement value of the source 1203c845caaSWilliam A. Kennington III * 1213c845caaSWilliam A. Kennington III * @param[in] enabled - The new state of the source 1223c845caaSWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1233c845caaSWilliam A. Kennington III */ 1248fd0cd4cSWilliam A. Kennington III void set_enabled(Enabled enabled) const; 12565db863eSWilliam A. Kennington III 126*43493b58SWilliam A. Kennington III /** @brief Determines the floating nature of the source 127*43493b58SWilliam A. Kennington III * 128*43493b58SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 129*43493b58SWilliam A. Kennington III * @return The enabled status of the source 130*43493b58SWilliam A. Kennington III */ 131*43493b58SWilliam A. Kennington III bool get_floating() const; 132*43493b58SWilliam A. Kennington III 133*43493b58SWilliam A. Kennington III /** @brief Sets the floating nature of the source 134*43493b58SWilliam A. Kennington III * If set to true, the source will continue to run after the 135*43493b58SWilliam A. Kennington III * destruction of this handle. 136*43493b58SWilliam A. Kennington III * 137*43493b58SWilliam A. Kennington III * @param[in] b - Whether or not the source should float 138*43493b58SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 139*43493b58SWilliam A. Kennington III */ 140*43493b58SWilliam A. Kennington III void set_floating(bool b) const; 141*43493b58SWilliam A. Kennington III 1420a816c5dSWilliam A. Kennington III protected: 143cc6b12beSWilliam A. Kennington III Event event; 1440a816c5dSWilliam A. Kennington III 145bc4e4569SWilliam A. Kennington III /** @brief Constructs a basic event source wrapper 146bc4e4569SWilliam A. Kennington III * Owns the passed reference to the source 147bc4e4569SWilliam A. Kennington III * This ownership is exception safe and will properly free the 148bc4e4569SWilliam A. Kennington III * source in the case of an exception during construction 149bc4e4569SWilliam A. Kennington III * 150bc4e4569SWilliam A. Kennington III * @param[in] event - The event associated with the source 151bc4e4569SWilliam A. Kennington III * @param[in] source - The underlying sd_event_source wrapped 1522301d47fSWilliam A. Kennington III * @param[in] - Signifies that ownership is being transfered 153bc4e4569SWilliam A. Kennington III */ 154715c72f8SWilliam A. Kennington III Base(const Event& event, sd_event_source* source, std::false_type); 15548c42751SWilliam A. Kennington III 1565320b1f5SWilliam A. Kennington III /** @brief Constructs a basic non-owning event source wrapper 1575320b1f5SWilliam A. Kennington III * Does not own the passed reference to the source because 1585320b1f5SWilliam A. Kennington III * this is meant to be used only as a reference inside an event 1595320b1f5SWilliam A. Kennington III * source. 1605320b1f5SWilliam A. Kennington III * @internal 1615320b1f5SWilliam A. Kennington III * 1625320b1f5SWilliam A. Kennington III * @param[in] other - The source wrapper to copy 1635320b1f5SWilliam A. Kennington III * @param[in] - Signifies that this new copy is non-owning 1645320b1f5SWilliam A. Kennington III */ 1655320b1f5SWilliam A. Kennington III Base(const Base& other, sdeventplus::internal::NoOwn); 1665320b1f5SWilliam A. Kennington III 1675320b1f5SWilliam A. Kennington III /** @brief Sets the userdata of the source to the passed in source 1685320b1f5SWilliam A. Kennington III * This needs to be called by all source implementors. 1695320b1f5SWilliam A. Kennington III * 1705320b1f5SWilliam A. Kennington III * @param[in] data - The data stored in the userdata slot. 1715320b1f5SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1725320b1f5SWilliam A. Kennington III */ 1735320b1f5SWilliam A. Kennington III void set_userdata(std::unique_ptr<detail::BaseData> data) const; 1745320b1f5SWilliam A. Kennington III 1755320b1f5SWilliam A. Kennington III /** @brief Get the heap allocated version of the Base 1765320b1f5SWilliam A. Kennington III * 1775320b1f5SWilliam A. Kennington III * @return A reference to the Base 1785320b1f5SWilliam A. Kennington III */ 1795320b1f5SWilliam A. Kennington III detail::BaseData& get_userdata() const; 180cc6b12beSWilliam A. Kennington III 181bc4e4569SWilliam A. Kennington III /** @brief Returns a reference to the prepare callback executed for this 182bc4e4569SWilliam A. Kennington III * source 183bc4e4569SWilliam A. Kennington III * 184bc4e4569SWilliam A. Kennington III * @return A reference to the callback, this should be checked to make sure 185bc4e4569SWilliam A. Kennington III * the callback is valid as there is no guarantee 186bc4e4569SWilliam A. Kennington III */ 187220b5dabSWilliam A. Kennington III Callback& get_prepare(); 188e0f1d199SWilliam A. Kennington III 189bc4e4569SWilliam A. Kennington III /** @brief A helper for subclasses to trivially wrap a c++ style callback 190bc4e4569SWilliam A. Kennington III * to be called from the sd-event c library 191bc4e4569SWilliam A. Kennington III * 192bc4e4569SWilliam A. Kennington III * @param[in] name - The name of the callback for use in error messages 193bc4e4569SWilliam A. Kennington III * @param[in] source - The sd_event_source provided by sd-event 194bc4e4569SWilliam A. Kennington III * @param[in] userdata - The userdata provided by sd-event 195bc4e4569SWilliam A. Kennington III * @param[in] args... - Extra arguments to pass to the callaback 196bc4e4569SWilliam A. Kennington III * @return An negative errno on error, or 0 on success 197bc4e4569SWilliam A. Kennington III */ 1985320b1f5SWilliam A. Kennington III template <typename Callback, class Data, auto getter, typename... Args> 199e0f1d199SWilliam A. Kennington III static int sourceCallback(const char* name, sd_event_source*, 2001e125d97SWilliam A. Kennington III void* userdata, Args&&... args) 201e0f1d199SWilliam A. Kennington III { 202e0f1d199SWilliam A. Kennington III if (userdata == nullptr) 203e0f1d199SWilliam A. Kennington III { 204e0f1d199SWilliam A. Kennington III fprintf(stderr, "sdeventplus: %s: Missing userdata\n", name); 205e0f1d199SWilliam A. Kennington III return -EINVAL; 206e0f1d199SWilliam A. Kennington III } 2075320b1f5SWilliam A. Kennington III Data& data = 2085320b1f5SWilliam A. Kennington III static_cast<Data&>(*reinterpret_cast<detail::BaseData*>(userdata)); 2095320b1f5SWilliam A. Kennington III Callback& callback = std::invoke(getter, data); 2105320b1f5SWilliam A. Kennington III return internal::performCallback(name, callback, std::ref(data), 2111e125d97SWilliam A. Kennington III std::forward<Args>(args)...); 212e0f1d199SWilliam A. Kennington III } 213e0f1d199SWilliam A. Kennington III 21448c42751SWilliam A. Kennington III private: 21556dc78baSWilliam A. Kennington III static sd_event_source* ref(sd_event_source* const& source, 21656dc78baSWilliam A. Kennington III const internal::SdEvent*& sdevent, bool& owned); 217e04cb03bSWilliam A. Kennington III static void drop(sd_event_source*&& source, 2185320b1f5SWilliam A. Kennington III const internal::SdEvent*& sdevent, bool& owned); 219e04cb03bSWilliam A. Kennington III 22056dc78baSWilliam A. Kennington III stdplus::Copyable<sd_event_source*, const internal::SdEvent*, 22156dc78baSWilliam A. Kennington III bool>::Handle<drop, ref> 222e04cb03bSWilliam A. Kennington III source; 2232d943eadSWilliam A. Kennington III 2245320b1f5SWilliam A. Kennington III /** @brief A wrapper around deleting the heap allocated base class 2255320b1f5SWilliam A. Kennington III * This is needed for calls from sd_event destroy callbacks. 226bc4e4569SWilliam A. Kennington III * 2275320b1f5SWilliam A. Kennington III * @param[in] userdata - The provided userdata for the source 228bc4e4569SWilliam A. Kennington III */ 2295320b1f5SWilliam A. Kennington III static void destroy_userdata(void* userdata); 230bc4e4569SWilliam A. Kennington III 231bc4e4569SWilliam A. Kennington III /** @brief A wrapper around the callback that can be called from sd-event 232bc4e4569SWilliam A. Kennington III * 233bc4e4569SWilliam A. Kennington III * @param[in] source - The sd_event_source associated with the call 234bc4e4569SWilliam A. Kennington III * @param[in] userdata - The provided userdata for the source 235bc4e4569SWilliam A. Kennington III * @return 0 on success or a negative errno otherwise 236bc4e4569SWilliam A. Kennington III */ 237e0f1d199SWilliam A. Kennington III static int prepareCallback(sd_event_source* source, void* userdata); 2380a816c5dSWilliam A. Kennington III }; 2390a816c5dSWilliam A. Kennington III 2405320b1f5SWilliam A. Kennington III namespace detail 2415320b1f5SWilliam A. Kennington III { 2425320b1f5SWilliam A. Kennington III 2435320b1f5SWilliam A. Kennington III class BaseData : public Base 2445320b1f5SWilliam A. Kennington III { 2455320b1f5SWilliam A. Kennington III private: 2465320b1f5SWilliam A. Kennington III Base::Callback prepare; 2475320b1f5SWilliam A. Kennington III 2485320b1f5SWilliam A. Kennington III public: 2495320b1f5SWilliam A. Kennington III BaseData(const Base& base); 2505320b1f5SWilliam A. Kennington III 2515320b1f5SWilliam A. Kennington III friend Base; 2525320b1f5SWilliam A. Kennington III }; 2535320b1f5SWilliam A. Kennington III 2545320b1f5SWilliam A. Kennington III } // namespace detail 2555320b1f5SWilliam A. Kennington III 2560a816c5dSWilliam A. Kennington III } // namespace source 2570a816c5dSWilliam A. Kennington III } // namespace sdeventplus 258