10a816c5dSWilliam A. Kennington III #pragma once
20a816c5dSWilliam A. Kennington III 
3*e0f1d199SWilliam A. Kennington III #include <cerrno>
465db863eSWilliam A. Kennington III #include <cstdint>
5*e0f1d199SWilliam 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>
9*e0f1d199SWilliam 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 
180a816c5dSWilliam A. Kennington III class Base
190a816c5dSWilliam A. Kennington III {
200a816c5dSWilliam A. Kennington III   public:
2148c42751SWilliam A. Kennington III     using Callback = std::function<void(Base& source)>;
2248c42751SWilliam A. Kennington III 
2365db863eSWilliam A. Kennington III     virtual ~Base();
2465db863eSWilliam A. Kennington III 
254863b96bSWilliam A. Kennington III     sd_event_source* get() const;
26715c72f8SWilliam A. Kennington III     const Event& get_event() const;
27715c72f8SWilliam A. Kennington III 
28d9fd9815SWilliam A. Kennington III     const char* get_description() const;
29d9fd9815SWilliam A. Kennington III     void set_description(const char* description) const;
3048c42751SWilliam A. Kennington III     void set_prepare(Callback&& callback);
31d9fd9815SWilliam A. Kennington III     int get_pending() const;
32d9fd9815SWilliam A. Kennington III     int64_t get_priority() const;
33d9fd9815SWilliam A. Kennington III     void set_priority(int64_t priority) const;
34d9fd9815SWilliam A. Kennington III     int get_enabled() const;
35d9fd9815SWilliam A. Kennington III     void set_enabled(int enabled) const;
3665db863eSWilliam A. Kennington III 
370a816c5dSWilliam A. Kennington III   protected:
38cc6b12beSWilliam A. Kennington III     Event event;
39cc6b12beSWilliam A. Kennington III     internal::SdRef<sd_event_source> source;
400a816c5dSWilliam A. Kennington III 
410a816c5dSWilliam A. Kennington III     // Base sources cannot be directly constructed.
42715c72f8SWilliam A. Kennington III     Base(const Event& event, sd_event_source* source);
43715c72f8SWilliam A. Kennington III     Base(const Event& event, sd_event_source* source, std::false_type);
4448c42751SWilliam A. Kennington III 
45cc6b12beSWilliam A. Kennington III     // We can't ever copy an event_source because the callback
46cc6b12beSWilliam A. Kennington III     // data has to be unique.
47cc6b12beSWilliam A. Kennington III     Base(const Base& other) = delete;
48cc6b12beSWilliam A. Kennington III     Base& operator=(const Base& other) = delete;
49cc6b12beSWilliam A. Kennington III     // We don't want to allow any kind of slicing.
502d943eadSWilliam A. Kennington III     Base(Base&& other);
51cc6b12beSWilliam A. Kennington III     Base& operator=(Base&& other);
52cc6b12beSWilliam A. Kennington III 
53*e0f1d199SWilliam A. Kennington III     const Callback& get_prepare() const;
54*e0f1d199SWilliam A. Kennington III 
55*e0f1d199SWilliam A. Kennington III     template <typename Callback, class Source,
56*e0f1d199SWilliam A. Kennington III               const Callback& (Source::*getter)() const, typename... Args>
57*e0f1d199SWilliam A. Kennington III     static int sourceCallback(const char* name, sd_event_source*,
58*e0f1d199SWilliam A. Kennington III                               void* userdata, Args... args)
59*e0f1d199SWilliam A. Kennington III     {
60*e0f1d199SWilliam A. Kennington III         if (userdata == nullptr)
61*e0f1d199SWilliam A. Kennington III         {
62*e0f1d199SWilliam A. Kennington III             fprintf(stderr, "sdeventplus: %s: Missing userdata\n", name);
63*e0f1d199SWilliam A. Kennington III             return -EINVAL;
64*e0f1d199SWilliam A. Kennington III         }
65*e0f1d199SWilliam A. Kennington III         Source* source = reinterpret_cast<Source*>(userdata);
66*e0f1d199SWilliam A. Kennington III         return internal::performCallback(name, (source->*getter)(),
67*e0f1d199SWilliam A. Kennington III                                          std::ref(*source), args...);
68*e0f1d199SWilliam A. Kennington III     }
69*e0f1d199SWilliam A. Kennington III 
7048c42751SWilliam A. Kennington III   private:
7148c42751SWilliam A. Kennington III     Callback prepare;
722d943eadSWilliam A. Kennington III 
732d943eadSWilliam A. Kennington III     void set_userdata();
74*e0f1d199SWilliam A. Kennington III     static int prepareCallback(sd_event_source* source, void* userdata);
750a816c5dSWilliam A. Kennington III };
760a816c5dSWilliam A. Kennington III 
770a816c5dSWilliam A. Kennington III } // namespace source
780a816c5dSWilliam A. Kennington III } // namespace sdeventplus
79