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> 12*56dc78baSWilliam 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; 49*56dc78baSWilliam A. Kennington III Base(const Base& other) = default; 50*56dc78baSWilliam 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 1260a816c5dSWilliam A. Kennington III protected: 127cc6b12beSWilliam A. Kennington III Event event; 1280a816c5dSWilliam A. Kennington III 129bc4e4569SWilliam A. Kennington III /** @brief Constructs a basic event source wrapper 130bc4e4569SWilliam A. Kennington III * Owns the passed reference to the source 131bc4e4569SWilliam A. Kennington III * This ownership is exception safe and will properly free the 132bc4e4569SWilliam A. Kennington III * source in the case of an exception during construction 133bc4e4569SWilliam A. Kennington III * 134bc4e4569SWilliam A. Kennington III * @param[in] event - The event associated with the source 135bc4e4569SWilliam A. Kennington III * @param[in] source - The underlying sd_event_source wrapped 1362301d47fSWilliam A. Kennington III * @param[in] - Signifies that ownership is being transfered 137bc4e4569SWilliam A. Kennington III */ 138715c72f8SWilliam A. Kennington III Base(const Event& event, sd_event_source* source, std::false_type); 13948c42751SWilliam A. Kennington III 1405320b1f5SWilliam A. Kennington III /** @brief Constructs a basic non-owning event source wrapper 1415320b1f5SWilliam A. Kennington III * Does not own the passed reference to the source because 1425320b1f5SWilliam A. Kennington III * this is meant to be used only as a reference inside an event 1435320b1f5SWilliam A. Kennington III * source. 1445320b1f5SWilliam A. Kennington III * @internal 1455320b1f5SWilliam A. Kennington III * 1465320b1f5SWilliam A. Kennington III * @param[in] other - The source wrapper to copy 1475320b1f5SWilliam A. Kennington III * @param[in] - Signifies that this new copy is non-owning 1485320b1f5SWilliam A. Kennington III */ 1495320b1f5SWilliam A. Kennington III Base(const Base& other, sdeventplus::internal::NoOwn); 1505320b1f5SWilliam A. Kennington III 1515320b1f5SWilliam A. Kennington III /** @brief Sets the userdata of the source to the passed in source 1525320b1f5SWilliam A. Kennington III * This needs to be called by all source implementors. 1535320b1f5SWilliam A. Kennington III * 1545320b1f5SWilliam A. Kennington III * @param[in] data - The data stored in the userdata slot. 1555320b1f5SWilliam A. Kennington III * @throws SdEventError for underlying sd_event errors 1565320b1f5SWilliam A. Kennington III */ 1575320b1f5SWilliam A. Kennington III void set_userdata(std::unique_ptr<detail::BaseData> data) const; 1585320b1f5SWilliam A. Kennington III 1595320b1f5SWilliam A. Kennington III /** @brief Get the heap allocated version of the Base 1605320b1f5SWilliam A. Kennington III * 1615320b1f5SWilliam A. Kennington III * @return A reference to the Base 1625320b1f5SWilliam A. Kennington III */ 1635320b1f5SWilliam A. Kennington III detail::BaseData& get_userdata() const; 164cc6b12beSWilliam A. Kennington III 165bc4e4569SWilliam A. Kennington III /** @brief Returns a reference to the prepare callback executed for this 166bc4e4569SWilliam A. Kennington III * source 167bc4e4569SWilliam A. Kennington III * 168bc4e4569SWilliam A. Kennington III * @return A reference to the callback, this should be checked to make sure 169bc4e4569SWilliam A. Kennington III * the callback is valid as there is no guarantee 170bc4e4569SWilliam A. Kennington III */ 171220b5dabSWilliam A. Kennington III Callback& get_prepare(); 172e0f1d199SWilliam A. Kennington III 173bc4e4569SWilliam A. Kennington III /** @brief A helper for subclasses to trivially wrap a c++ style callback 174bc4e4569SWilliam A. Kennington III * to be called from the sd-event c library 175bc4e4569SWilliam A. Kennington III * 176bc4e4569SWilliam A. Kennington III * @param[in] name - The name of the callback for use in error messages 177bc4e4569SWilliam A. Kennington III * @param[in] source - The sd_event_source provided by sd-event 178bc4e4569SWilliam A. Kennington III * @param[in] userdata - The userdata provided by sd-event 179bc4e4569SWilliam A. Kennington III * @param[in] args... - Extra arguments to pass to the callaback 180bc4e4569SWilliam A. Kennington III * @return An negative errno on error, or 0 on success 181bc4e4569SWilliam A. Kennington III */ 1825320b1f5SWilliam A. Kennington III template <typename Callback, class Data, auto getter, typename... Args> 183e0f1d199SWilliam A. Kennington III static int sourceCallback(const char* name, sd_event_source*, 1841e125d97SWilliam A. Kennington III void* userdata, Args&&... args) 185e0f1d199SWilliam A. Kennington III { 186e0f1d199SWilliam A. Kennington III if (userdata == nullptr) 187e0f1d199SWilliam A. Kennington III { 188e0f1d199SWilliam A. Kennington III fprintf(stderr, "sdeventplus: %s: Missing userdata\n", name); 189e0f1d199SWilliam A. Kennington III return -EINVAL; 190e0f1d199SWilliam A. Kennington III } 1915320b1f5SWilliam A. Kennington III Data& data = 1925320b1f5SWilliam A. Kennington III static_cast<Data&>(*reinterpret_cast<detail::BaseData*>(userdata)); 1935320b1f5SWilliam A. Kennington III Callback& callback = std::invoke(getter, data); 1945320b1f5SWilliam A. Kennington III return internal::performCallback(name, callback, std::ref(data), 1951e125d97SWilliam A. Kennington III std::forward<Args>(args)...); 196e0f1d199SWilliam A. Kennington III } 197e0f1d199SWilliam A. Kennington III 19848c42751SWilliam A. Kennington III private: 199*56dc78baSWilliam A. Kennington III static sd_event_source* ref(sd_event_source* const& source, 200*56dc78baSWilliam A. Kennington III const internal::SdEvent*& sdevent, bool& owned); 201e04cb03bSWilliam A. Kennington III static void drop(sd_event_source*&& source, 2025320b1f5SWilliam A. Kennington III const internal::SdEvent*& sdevent, bool& owned); 203e04cb03bSWilliam A. Kennington III 204*56dc78baSWilliam A. Kennington III stdplus::Copyable<sd_event_source*, const internal::SdEvent*, 205*56dc78baSWilliam A. Kennington III bool>::Handle<drop, ref> 206e04cb03bSWilliam A. Kennington III source; 2072d943eadSWilliam A. Kennington III 2085320b1f5SWilliam A. Kennington III /** @brief A wrapper around deleting the heap allocated base class 2095320b1f5SWilliam A. Kennington III * This is needed for calls from sd_event destroy callbacks. 210bc4e4569SWilliam A. Kennington III * 2115320b1f5SWilliam A. Kennington III * @param[in] userdata - The provided userdata for the source 212bc4e4569SWilliam A. Kennington III */ 2135320b1f5SWilliam A. Kennington III static void destroy_userdata(void* userdata); 214bc4e4569SWilliam A. Kennington III 215bc4e4569SWilliam A. Kennington III /** @brief A wrapper around the callback that can be called from sd-event 216bc4e4569SWilliam A. Kennington III * 217bc4e4569SWilliam A. Kennington III * @param[in] source - The sd_event_source associated with the call 218bc4e4569SWilliam A. Kennington III * @param[in] userdata - The provided userdata for the source 219bc4e4569SWilliam A. Kennington III * @return 0 on success or a negative errno otherwise 220bc4e4569SWilliam A. Kennington III */ 221e0f1d199SWilliam A. Kennington III static int prepareCallback(sd_event_source* source, void* userdata); 2220a816c5dSWilliam A. Kennington III }; 2230a816c5dSWilliam A. Kennington III 2245320b1f5SWilliam A. Kennington III namespace detail 2255320b1f5SWilliam A. Kennington III { 2265320b1f5SWilliam A. Kennington III 2275320b1f5SWilliam A. Kennington III class BaseData : public Base 2285320b1f5SWilliam A. Kennington III { 2295320b1f5SWilliam A. Kennington III private: 2305320b1f5SWilliam A. Kennington III Base::Callback prepare; 2315320b1f5SWilliam A. Kennington III 2325320b1f5SWilliam A. Kennington III public: 2335320b1f5SWilliam A. Kennington III BaseData(const Base& base); 2345320b1f5SWilliam A. Kennington III 2355320b1f5SWilliam A. Kennington III friend Base; 2365320b1f5SWilliam A. Kennington III }; 2375320b1f5SWilliam A. Kennington III 2385320b1f5SWilliam A. Kennington III } // namespace detail 2395320b1f5SWilliam A. Kennington III 2400a816c5dSWilliam A. Kennington III } // namespace source 2410a816c5dSWilliam A. Kennington III } // namespace sdeventplus 242