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*3c845caaSWilliam A. Kennington III /** @class Base
19*3c845caaSWilliam A. Kennington III  *  @brief The base class for all sources implementing common source methods
20*3c845caaSWilliam A. Kennington III  *         Not instantiated directly by end users
21*3c845caaSWilliam A. Kennington III  */
220a816c5dSWilliam A. Kennington III class Base
230a816c5dSWilliam A. Kennington III {
240a816c5dSWilliam A. Kennington III   public:
2548c42751SWilliam A. Kennington III     using Callback = std::function<void(Base& source)>;
2648c42751SWilliam A. Kennington III 
2765db863eSWilliam A. Kennington III     virtual ~Base();
2865db863eSWilliam A. Kennington III 
29*3c845caaSWilliam A. Kennington III     /** @brief Gets the underlying sd_event_source
30*3c845caaSWilliam A. Kennington III      *
31*3c845caaSWilliam A. Kennington III      *  @return The sd_event_source
32*3c845caaSWilliam A. Kennington III      */
334863b96bSWilliam A. Kennington III     sd_event_source* get() const;
34*3c845caaSWilliam A. Kennington III 
35*3c845caaSWilliam A. Kennington III     /** @brief Gets the associated Event object
36*3c845caaSWilliam A. Kennington III      *
37*3c845caaSWilliam A. Kennington III      *  @return The Event
38*3c845caaSWilliam A. Kennington III      */
39715c72f8SWilliam A. Kennington III     const Event& get_event() const;
40715c72f8SWilliam A. Kennington III 
41*3c845caaSWilliam A. Kennington III     /** @brief Gets the description of the source
42*3c845caaSWilliam A. Kennington III      *
43*3c845caaSWilliam A. Kennington III      *  @throws SdEventError for underlying sd_event errors
44*3c845caaSWilliam A. Kennington III      *  @return The c-string description or a nullptr if none exists
45*3c845caaSWilliam A. Kennington III      */
46d9fd9815SWilliam A. Kennington III     const char* get_description() const;
47*3c845caaSWilliam A. Kennington III 
48*3c845caaSWilliam A. Kennington III     /** @brief Sets the description of the source
49*3c845caaSWilliam A. Kennington III      *
50*3c845caaSWilliam A. Kennington III      *  @param[in] description - The c-string description
51*3c845caaSWilliam A. Kennington III      *  @throws SdEventError for underlying sd_event errors
52*3c845caaSWilliam A. Kennington III      */
53d9fd9815SWilliam A. Kennington III     void set_description(const char* description) const;
54*3c845caaSWilliam A. Kennington III 
55*3c845caaSWilliam A. Kennington III     /** @brief Sets the callback associated with the source to be performed
56*3c845caaSWilliam A. Kennington III      *         before the event loop goes to sleep, waiting for new events
57*3c845caaSWilliam A. Kennington III      *
58*3c845caaSWilliam A. Kennington III      *  @param[in] callback - Function run for preparation of the source
59*3c845caaSWilliam A. Kennington III      *  @throws SdEventError for underlying sd_event errors
60*3c845caaSWilliam A. Kennington III      */
6148c42751SWilliam A. Kennington III     void set_prepare(Callback&& callback);
62*3c845caaSWilliam A. Kennington III 
63*3c845caaSWilliam A. Kennington III     /** @brief Whether or not the source has any pending events that have
64*3c845caaSWilliam A. Kennington III      *         not been dispatched yet.
65*3c845caaSWilliam A. Kennington III      *
66*3c845caaSWilliam A. Kennington III      *  @throws SdEventError for underlying sd_event errors
67*3c845caaSWilliam A. Kennington III      *  @return 'true' if the source has pending events
68*3c845caaSWilliam A. Kennington III      *          'false' otherwise
69*3c845caaSWilliam A. Kennington III      */
70d9fd9815SWilliam A. Kennington III     int get_pending() const;
71*3c845caaSWilliam A. Kennington III 
72*3c845caaSWilliam A. Kennington III     /** @brief Gets the priority of the source relative to other sources
73*3c845caaSWilliam A. Kennington III      *         The lower the priority the more important the source
74*3c845caaSWilliam A. Kennington III      *
75*3c845caaSWilliam A. Kennington III      *  @throws SdEventError for underlying sd_event errors
76*3c845caaSWilliam A. Kennington III      *  @return A 64 bit integer representing the dispatch priority
77*3c845caaSWilliam A. Kennington III      */
78d9fd9815SWilliam A. Kennington III     int64_t get_priority() const;
79*3c845caaSWilliam A. Kennington III 
80*3c845caaSWilliam A. Kennington III     /** @brief Sets the priority of the source relative to other sources
81*3c845caaSWilliam A. Kennington III      *         The lower the priority the more important the source
82*3c845caaSWilliam A. Kennington III      *
83*3c845caaSWilliam A. Kennington III      *  @param[in] priority - A 64 bit integer representing the priority
84*3c845caaSWilliam A. Kennington III      *  @throws SdEventError for underlying sd_event errors
85*3c845caaSWilliam A. Kennington III      */
86d9fd9815SWilliam A. Kennington III     void set_priority(int64_t priority) const;
87*3c845caaSWilliam A. Kennington III 
88*3c845caaSWilliam A. Kennington III     /** @brief Determines the enablement value of the source
89*3c845caaSWilliam A. Kennington III      *
90*3c845caaSWilliam A. Kennington III      *  @throws SdEventError for underlying sd_event errors
91*3c845caaSWilliam A. Kennington III      *  @return The enabled status of the source
92*3c845caaSWilliam A. Kennington III      */
93d9fd9815SWilliam A. Kennington III     int get_enabled() const;
94*3c845caaSWilliam A. Kennington III 
95*3c845caaSWilliam A. Kennington III     /** @brief Sets the enablement value of the source
96*3c845caaSWilliam A. Kennington III      *
97*3c845caaSWilliam A. Kennington III      *  @param[in] enabled - The new state of the source
98*3c845caaSWilliam A. Kennington III      *  @throws SdEventError for underlying sd_event errors
99*3c845caaSWilliam A. Kennington III      */
100d9fd9815SWilliam A. Kennington III     void set_enabled(int enabled) const;
10165db863eSWilliam A. Kennington III 
1020a816c5dSWilliam A. Kennington III   protected:
103cc6b12beSWilliam A. Kennington III     Event event;
104cc6b12beSWilliam A. Kennington III     internal::SdRef<sd_event_source> source;
1050a816c5dSWilliam A. Kennington III 
1060a816c5dSWilliam A. Kennington III     // Base sources cannot be directly constructed.
107715c72f8SWilliam A. Kennington III     Base(const Event& event, sd_event_source* source);
108715c72f8SWilliam A. Kennington III     Base(const Event& event, sd_event_source* source, std::false_type);
10948c42751SWilliam A. Kennington III 
110cc6b12beSWilliam A. Kennington III     // We can't ever copy an event_source because the callback
111cc6b12beSWilliam A. Kennington III     // data has to be unique.
112cc6b12beSWilliam A. Kennington III     Base(const Base& other) = delete;
113cc6b12beSWilliam A. Kennington III     Base& operator=(const Base& other) = delete;
114cc6b12beSWilliam A. Kennington III     // We don't want to allow any kind of slicing.
1152d943eadSWilliam A. Kennington III     Base(Base&& other);
116cc6b12beSWilliam A. Kennington III     Base& operator=(Base&& other);
117cc6b12beSWilliam A. Kennington III 
118e0f1d199SWilliam A. Kennington III     const Callback& get_prepare() const;
119e0f1d199SWilliam A. Kennington III 
120e0f1d199SWilliam A. Kennington III     template <typename Callback, class Source,
121e0f1d199SWilliam A. Kennington III               const Callback& (Source::*getter)() const, typename... Args>
122e0f1d199SWilliam A. Kennington III     static int sourceCallback(const char* name, sd_event_source*,
123e0f1d199SWilliam A. Kennington III                               void* userdata, Args... args)
124e0f1d199SWilliam A. Kennington III     {
125e0f1d199SWilliam A. Kennington III         if (userdata == nullptr)
126e0f1d199SWilliam A. Kennington III         {
127e0f1d199SWilliam A. Kennington III             fprintf(stderr, "sdeventplus: %s: Missing userdata\n", name);
128e0f1d199SWilliam A. Kennington III             return -EINVAL;
129e0f1d199SWilliam A. Kennington III         }
130e0f1d199SWilliam A. Kennington III         Source* source = reinterpret_cast<Source*>(userdata);
131e0f1d199SWilliam A. Kennington III         return internal::performCallback(name, (source->*getter)(),
132e0f1d199SWilliam A. Kennington III                                          std::ref(*source), args...);
133e0f1d199SWilliam A. Kennington III     }
134e0f1d199SWilliam A. Kennington III 
13548c42751SWilliam A. Kennington III   private:
13648c42751SWilliam A. Kennington III     Callback prepare;
1372d943eadSWilliam A. Kennington III 
1382d943eadSWilliam A. Kennington III     void set_userdata();
139e0f1d199SWilliam A. Kennington III     static int prepareCallback(sd_event_source* source, void* userdata);
1400a816c5dSWilliam A. Kennington III };
1410a816c5dSWilliam A. Kennington III 
1420a816c5dSWilliam A. Kennington III } // namespace source
1430a816c5dSWilliam A. Kennington III } // namespace sdeventplus
144