1 #pragma once 2 3 #include <cerrno> 4 #include <cstdint> 5 #include <cstdio> 6 #include <functional> 7 #include <sdeventplus/event.hpp> 8 #include <sdeventplus/internal/sdref.hpp> 9 #include <sdeventplus/internal/utils.hpp> 10 #include <systemd/sd-bus.h> 11 #include <type_traits> 12 13 namespace sdeventplus 14 { 15 namespace source 16 { 17 18 class Base 19 { 20 public: 21 using Callback = std::function<void(Base& source)>; 22 23 virtual ~Base(); 24 25 sd_event_source* get() const; 26 const Event& get_event() const; 27 28 const char* get_description() const; 29 void set_description(const char* description) const; 30 void set_prepare(Callback&& callback); 31 int get_pending() const; 32 int64_t get_priority() const; 33 void set_priority(int64_t priority) const; 34 int get_enabled() const; 35 void set_enabled(int enabled) const; 36 37 protected: 38 Event event; 39 internal::SdRef<sd_event_source> source; 40 41 // Base sources cannot be directly constructed. 42 Base(const Event& event, sd_event_source* source); 43 Base(const Event& event, sd_event_source* source, std::false_type); 44 45 // We can't ever copy an event_source because the callback 46 // data has to be unique. 47 Base(const Base& other) = delete; 48 Base& operator=(const Base& other) = delete; 49 // We don't want to allow any kind of slicing. 50 Base(Base&& other); 51 Base& operator=(Base&& other); 52 53 const Callback& get_prepare() const; 54 55 template <typename Callback, class Source, 56 const Callback& (Source::*getter)() const, typename... Args> 57 static int sourceCallback(const char* name, sd_event_source*, 58 void* userdata, Args... args) 59 { 60 if (userdata == nullptr) 61 { 62 fprintf(stderr, "sdeventplus: %s: Missing userdata\n", name); 63 return -EINVAL; 64 } 65 Source* source = reinterpret_cast<Source*>(userdata); 66 return internal::performCallback(name, (source->*getter)(), 67 std::ref(*source), args...); 68 } 69 70 private: 71 Callback prepare; 72 73 void set_userdata(); 74 static int prepareCallback(sd_event_source* source, void* userdata); 75 }; 76 77 } // namespace source 78 } // namespace sdeventplus 79