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 
18*8fd0cd4cSWilliam A. Kennington III /** @class Enabled
19*8fd0cd4cSWilliam A. Kennington III  *  @brief Mapping of sdeventplus source enable values to the sd-event
20*8fd0cd4cSWilliam A. Kennington III  *         equivalent
21*8fd0cd4cSWilliam A. Kennington III  */
22*8fd0cd4cSWilliam A. Kennington III enum class Enabled
23*8fd0cd4cSWilliam A. Kennington III {
24*8fd0cd4cSWilliam A. Kennington III     Off = SD_EVENT_OFF,
25*8fd0cd4cSWilliam A. Kennington III     On = SD_EVENT_ON,
26*8fd0cd4cSWilliam A. Kennington III     OneShot = SD_EVENT_ONESHOT,
27*8fd0cd4cSWilliam A. Kennington III };
28*8fd0cd4cSWilliam 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      */
81*8fd0cd4cSWilliam 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      */
104*8fd0cd4cSWilliam 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      */
111*8fd0cd4cSWilliam 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 
1170a816c5dSWilliam A. Kennington III     // Base sources cannot be directly constructed.
118715c72f8SWilliam A. Kennington III     Base(const Event& event, sd_event_source* source);
119715c72f8SWilliam A. Kennington III     Base(const Event& event, sd_event_source* source, std::false_type);
12048c42751SWilliam A. Kennington III 
121cc6b12beSWilliam A. Kennington III     // We can't ever copy an event_source because the callback
122cc6b12beSWilliam A. Kennington III     // data has to be unique.
123cc6b12beSWilliam A. Kennington III     Base(const Base& other) = delete;
124cc6b12beSWilliam A. Kennington III     Base& operator=(const Base& other) = delete;
125cc6b12beSWilliam A. Kennington III     // We don't want to allow any kind of slicing.
1262d943eadSWilliam A. Kennington III     Base(Base&& other);
127cc6b12beSWilliam A. Kennington III     Base& operator=(Base&& other);
128cc6b12beSWilliam A. Kennington III 
129e0f1d199SWilliam A. Kennington III     const Callback& get_prepare() const;
130e0f1d199SWilliam A. Kennington III 
131e0f1d199SWilliam A. Kennington III     template <typename Callback, class Source,
132e0f1d199SWilliam A. Kennington III               const Callback& (Source::*getter)() const, typename... Args>
133e0f1d199SWilliam A. Kennington III     static int sourceCallback(const char* name, sd_event_source*,
134e0f1d199SWilliam A. Kennington III                               void* userdata, Args... args)
135e0f1d199SWilliam A. Kennington III     {
136e0f1d199SWilliam A. Kennington III         if (userdata == nullptr)
137e0f1d199SWilliam A. Kennington III         {
138e0f1d199SWilliam A. Kennington III             fprintf(stderr, "sdeventplus: %s: Missing userdata\n", name);
139e0f1d199SWilliam A. Kennington III             return -EINVAL;
140e0f1d199SWilliam A. Kennington III         }
141e0f1d199SWilliam A. Kennington III         Source* source = reinterpret_cast<Source*>(userdata);
142e0f1d199SWilliam A. Kennington III         return internal::performCallback(name, (source->*getter)(),
143e0f1d199SWilliam A. Kennington III                                          std::ref(*source), args...);
144e0f1d199SWilliam A. Kennington III     }
145e0f1d199SWilliam A. Kennington III 
14648c42751SWilliam A. Kennington III   private:
14748c42751SWilliam A. Kennington III     Callback prepare;
1482d943eadSWilliam A. Kennington III 
1492d943eadSWilliam A. Kennington III     void set_userdata();
150e0f1d199SWilliam A. Kennington III     static int prepareCallback(sd_event_source* source, void* userdata);
1510a816c5dSWilliam A. Kennington III };
1520a816c5dSWilliam A. Kennington III 
1530a816c5dSWilliam A. Kennington III } // namespace source
1540a816c5dSWilliam A. Kennington III } // namespace sdeventplus
155