1 #include <functional>
2 #include <sdeventplus/internal/cexec.hpp>
3 #include <sdeventplus/internal/sdevent.hpp>
4 #include <sdeventplus/source/base.hpp>
5 #include <sdeventplus/types.hpp>
6 #include <utility>
7 
8 namespace sdeventplus
9 {
10 namespace source
11 {
12 
13 sd_event_source* Base::get() const
14 {
15     return source.value();
16 }
17 
18 const Event& Base::get_event() const
19 {
20     return event;
21 }
22 
23 const char* Base::get_description() const
24 {
25     const char* description;
26     SDEVENTPLUS_CHECK("sd_event_source_get_description",
27                       event.getSdEvent()->sd_event_source_get_description(
28                           get(), &description));
29     return description;
30 }
31 
32 void Base::set_description(const char* description) const
33 {
34     SDEVENTPLUS_CHECK("sd_event_source_set_description",
35                       event.getSdEvent()->sd_event_source_set_description(
36                           get(), description));
37 }
38 
39 void Base::set_prepare(Callback&& callback)
40 {
41     try
42     {
43         SDEVENTPLUS_CHECK("sd_event_source_set_prepare",
44                           event.getSdEvent()->sd_event_source_set_prepare(
45                               get(), callback ? prepareCallback : nullptr));
46         get_userdata().prepare = std::move(callback);
47     }
48     catch (...)
49     {
50         get_userdata().prepare = nullptr;
51         throw;
52     }
53 }
54 
55 bool Base::get_pending() const
56 {
57     return SDEVENTPLUS_CHECK(
58         "sd_event_source_get_pending",
59         event.getSdEvent()->sd_event_source_get_pending(get()));
60 }
61 
62 int64_t Base::get_priority() const
63 {
64     int64_t priority;
65     SDEVENTPLUS_CHECK(
66         "sd_event_source_get_priority",
67         event.getSdEvent()->sd_event_source_get_priority(get(), &priority));
68     return priority;
69 }
70 
71 void Base::set_priority(int64_t priority) const
72 {
73     SDEVENTPLUS_CHECK(
74         "sd_event_source_set_priority",
75         event.getSdEvent()->sd_event_source_set_priority(get(), priority));
76 }
77 
78 Enabled Base::get_enabled() const
79 {
80     int enabled;
81     SDEVENTPLUS_CHECK(
82         "sd_event_source_get_enabled",
83         event.getSdEvent()->sd_event_source_get_enabled(get(), &enabled));
84     return static_cast<Enabled>(enabled);
85 }
86 
87 void Base::set_enabled(Enabled enabled) const
88 {
89     SDEVENTPLUS_CHECK("sd_event_source_set_enabled",
90                       event.getSdEvent()->sd_event_source_set_enabled(
91                           get(), static_cast<int>(enabled)));
92 }
93 
94 bool Base::get_floating() const
95 {
96     return SDEVENTPLUS_CHECK(
97         "sd_event_source_get_floating",
98         event.getSdEvent()->sd_event_source_get_floating(get()));
99 }
100 
101 void Base::set_floating(bool b) const
102 {
103     SDEVENTPLUS_CHECK("sd_event_source_set_floating",
104                       event.getSdEvent()->sd_event_source_set_floating(
105                           get(), static_cast<int>(b)));
106 }
107 
108 Base::Base(const Event& event, sd_event_source* source, std::false_type) :
109     event(event), source(std::move(source), event.getSdEvent(), true)
110 {
111 }
112 
113 Base::Base(const Base& other, sdeventplus::internal::NoOwn) :
114     event(other.get_event(), sdeventplus::internal::NoOwn()),
115     source(other.get(), event.getSdEvent(), false)
116 {
117 }
118 
119 void Base::set_userdata(std::unique_ptr<detail::BaseData> data) const
120 {
121     SDEVENTPLUS_CHECK("sd_event_source_set_destroy_callback",
122                       event.getSdEvent()->sd_event_source_set_destroy_callback(
123                           get(), &Base::destroy_userdata));
124     event.getSdEvent()->sd_event_source_set_userdata(get(), data.release());
125 }
126 
127 detail::BaseData& Base::get_userdata() const
128 {
129     return *reinterpret_cast<detail::BaseData*>(
130         event.getSdEvent()->sd_event_source_get_userdata(get()));
131 }
132 
133 Base::Callback& Base::get_prepare()
134 {
135     return get_userdata().prepare;
136 }
137 
138 sd_event_source* Base::ref(sd_event_source* const& source,
139                            const internal::SdEvent*& sdevent, bool& owned)
140 {
141     owned = true;
142     return sdevent->sd_event_source_ref(source);
143 }
144 
145 void Base::drop(sd_event_source*&& source, const internal::SdEvent*& sdevent,
146                 bool& owned)
147 {
148     if (owned)
149     {
150         sdevent->sd_event_source_unref(source);
151     }
152 }
153 
154 void Base::destroy_userdata(void* userdata)
155 {
156     delete static_cast<Base*>(userdata);
157 }
158 
159 int Base::prepareCallback(sd_event_source* source, void* userdata)
160 {
161     return sourceCallback<Callback, Base, &Base::get_prepare>("prepareCallback",
162                                                               source, userdata);
163 }
164 
165 namespace detail
166 {
167 
168 BaseData::BaseData(const Base& base) :
169     Base(base, sdeventplus::internal::NoOwn())
170 {
171 }
172 
173 } // namespace detail
174 
175 } // namespace source
176 } // namespace sdeventplus
177