Bug Summary

File:build-scan/../src/libsystemd/sd-event/sd-event.c
Warning:line 2026, column 9
Value stored to 'rm_inode' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sd-event.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/libsystemd/libsystemd_static.a.p -I src/libsystemd -I ../src/libsystemd -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility default -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/libsystemd/sd-event/sd-event.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2/***
3***/
4
5#include <sys/epoll.h>
6#include <sys/timerfd.h>
7#include <sys/wait.h>
8
9#include "sd-daemon.h"
10#include "sd-event.h"
11#include "sd-id128.h"
12
13#include "alloc-util.h"
14#include "fd-util.h"
15#include "fs-util.h"
16#include "hashmap.h"
17#include "list.h"
18#include "macro.h"
19#include "missing.h"
20#include "prioq.h"
21#include "process-util.h"
22#include "ratelimit.h"
23#include "set.h"
24#include "signal-util.h"
25#include "string-table.h"
26#include "string-util.h"
27#include "time-util.h"
28#include "util.h"
29
30#define DEFAULT_ACCURACY_USEC(250 * ((usec_t) 1000ULL)) (250 * USEC_PER_MSEC((usec_t) 1000ULL))
31
32typedef enum EventSourceType {
33 SOURCE_IO,
34 SOURCE_TIME_REALTIME,
35 SOURCE_TIME_BOOTTIME,
36 SOURCE_TIME_MONOTONIC,
37 SOURCE_TIME_REALTIME_ALARM,
38 SOURCE_TIME_BOOTTIME_ALARM,
39 SOURCE_SIGNAL,
40 SOURCE_CHILD,
41 SOURCE_DEFER,
42 SOURCE_POST,
43 SOURCE_EXIT,
44 SOURCE_WATCHDOG,
45 SOURCE_INOTIFY,
46 _SOURCE_EVENT_SOURCE_TYPE_MAX,
47 _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1
48} EventSourceType;
49
50
51static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] = {
52 [SOURCE_IO] = "io",
53 [SOURCE_TIME_REALTIME] = "realtime",
54 [SOURCE_TIME_BOOTTIME] = "bootime",
55 [SOURCE_TIME_MONOTONIC] = "monotonic",
56 [SOURCE_TIME_REALTIME_ALARM] = "realtime-alarm",
57 [SOURCE_TIME_BOOTTIME_ALARM] = "boottime-alarm",
58 [SOURCE_SIGNAL] = "signal",
59 [SOURCE_CHILD] = "child",
60 [SOURCE_DEFER] = "defer",
61 [SOURCE_POST] = "post",
62 [SOURCE_EXIT] = "exit",
63 [SOURCE_WATCHDOG] = "watchdog",
64 [SOURCE_INOTIFY] = "inotify",
65};
66
67DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(event_source_type, int)static const char *event_source_type_to_string(int i) { if (i
< 0 || i >= (int) __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(event_source_type_table
), typeof(&*(event_source_type_table))), sizeof(event_source_type_table
)/sizeof((event_source_type_table)[0]), ((void)0)))) return (
(void*)0); return event_source_type_table[i]; }
;
68
69/* All objects we use in epoll events start with this value, so that
70 * we know how to dispatch it */
71typedef enum WakeupType {
72 WAKEUP_NONE,
73 WAKEUP_EVENT_SOURCE,
74 WAKEUP_CLOCK_DATA,
75 WAKEUP_SIGNAL_DATA,
76 WAKEUP_INOTIFY_DATA,
77 _WAKEUP_TYPE_MAX,
78 _WAKEUP_TYPE_INVALID = -1,
79} WakeupType;
80
81#define EVENT_SOURCE_IS_TIME(t)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((t)) { case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: _found = 1; break; default
: break; } _found; })
\
82 IN_SET((t), \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((t)) { case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: _found = 1; break; default
: break; } _found; })
83 SOURCE_TIME_REALTIME, \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((t)) { case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: _found = 1; break; default
: break; } _found; })
84 SOURCE_TIME_BOOTTIME, \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((t)) { case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: _found = 1; break; default
: break; } _found; })
85 SOURCE_TIME_MONOTONIC, \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((t)) { case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: _found = 1; break; default
: break; } _found; })
86 SOURCE_TIME_REALTIME_ALARM, \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((t)) { case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: _found = 1; break; default
: break; } _found; })
87 SOURCE_TIME_BOOTTIME_ALARM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((t)) { case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: _found = 1; break; default
: break; } _found; })
88
89#define EVENT_SOURCE_CAN_RATE_LIMIT(t)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((t)) { case SOURCE_IO: case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: case SOURCE_SIGNAL: case SOURCE_DEFER
: case SOURCE_INOTIFY: _found = 1; break; default: break; } _found
; })
\
90 IN_SET((t), \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((t)) { case SOURCE_IO: case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: case SOURCE_SIGNAL: case SOURCE_DEFER
: case SOURCE_INOTIFY: _found = 1; break; default: break; } _found
; })
91 SOURCE_IO, \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((t)) { case SOURCE_IO: case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: case SOURCE_SIGNAL: case SOURCE_DEFER
: case SOURCE_INOTIFY: _found = 1; break; default: break; } _found
; })
92 SOURCE_TIME_REALTIME, \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((t)) { case SOURCE_IO: case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: case SOURCE_SIGNAL: case SOURCE_DEFER
: case SOURCE_INOTIFY: _found = 1; break; default: break; } _found
; })
93 SOURCE_TIME_BOOTTIME, \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((t)) { case SOURCE_IO: case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: case SOURCE_SIGNAL: case SOURCE_DEFER
: case SOURCE_INOTIFY: _found = 1; break; default: break; } _found
; })
94 SOURCE_TIME_MONOTONIC, \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((t)) { case SOURCE_IO: case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: case SOURCE_SIGNAL: case SOURCE_DEFER
: case SOURCE_INOTIFY: _found = 1; break; default: break; } _found
; })
95 SOURCE_TIME_REALTIME_ALARM, \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((t)) { case SOURCE_IO: case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: case SOURCE_SIGNAL: case SOURCE_DEFER
: case SOURCE_INOTIFY: _found = 1; break; default: break; } _found
; })
96 SOURCE_TIME_BOOTTIME_ALARM, \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((t)) { case SOURCE_IO: case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: case SOURCE_SIGNAL: case SOURCE_DEFER
: case SOURCE_INOTIFY: _found = 1; break; default: break; } _found
; })
97 SOURCE_SIGNAL, \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((t)) { case SOURCE_IO: case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: case SOURCE_SIGNAL: case SOURCE_DEFER
: case SOURCE_INOTIFY: _found = 1; break; default: break; } _found
; })
98 SOURCE_DEFER, \({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((t)) { case SOURCE_IO: case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: case SOURCE_SIGNAL: case SOURCE_DEFER
: case SOURCE_INOTIFY: _found = 1; break; default: break; } _found
; })
99 SOURCE_INOTIFY)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((t)) { case SOURCE_IO: case SOURCE_TIME_REALTIME: case
SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case SOURCE_TIME_REALTIME_ALARM
: case SOURCE_TIME_BOOTTIME_ALARM: case SOURCE_SIGNAL: case SOURCE_DEFER
: case SOURCE_INOTIFY: _found = 1; break; default: break; } _found
; })
100
101struct inode_data;
102
103struct sd_event_source {
104 WakeupType wakeup;
105
106 unsigned n_ref;
107
108 sd_event *event;
109 void *userdata;
110 sd_event_handler_t prepare;
111
112 char *description;
113
114 EventSourceType type:5;
115 int enabled:3;
116 bool_Bool pending:1;
117 bool_Bool dispatching:1;
118 bool_Bool floating:1;
119 bool_Bool ratelimited:1;
120
121 int64_t priority;
122 unsigned pending_index;
123 unsigned prepare_index;
124 uint64_t pending_iteration;
125 uint64_t prepare_iteration;
126
127 sd_event_destroy_t destroy_callback;
128
129 LIST_FIELDS(sd_event_source, sources)sd_event_source *sources_next, *sources_prev;
130
131 RateLimit rate_limit;
132
133 /* These are primarily fields relevant for time event sources, but since any event source can
134 * effectively become one when rate-limited, this is part of the common fields. */
135 unsigned earliest_index;
136 unsigned latest_index;
137
138 union {
139 struct {
140 sd_event_io_handler_t callback;
141 int fd;
142 uint32_t events;
143 uint32_t revents;
144 bool_Bool registered:1;
145 bool_Bool owned:1;
146 } io;
147 struct {
148 sd_event_time_handler_t callback;
149 usec_t next, accuracy;
150 } time;
151 struct {
152 sd_event_signal_handler_t callback;
153 struct signalfd_siginfo siginfo;
154 int sig;
155 } signal;
156 struct {
157 sd_event_child_handler_t callback;
158 siginfo_t siginfo;
159 pid_t pid;
160 int options;
161 } child;
162 struct {
163 sd_event_handler_t callback;
164 } defer;
165 struct {
166 sd_event_handler_t callback;
167 } post;
168 struct {
169 sd_event_handler_t callback;
170 unsigned prioq_index;
171 } exit;
172 struct {
173 sd_event_inotify_handler_t callback;
174 uint32_t mask;
175 struct inode_data *inode_data;
176 LIST_FIELDS(sd_event_source, by_inode_data)sd_event_source *by_inode_data_next, *by_inode_data_prev;
177 } inotify;
178 };
179};
180
181struct clock_data {
182 WakeupType wakeup;
183 int fd;
184
185 /* For all clocks we maintain two priority queues each, one
186 * ordered for the earliest times the events may be
187 * dispatched, and one ordered by the latest times they must
188 * have been dispatched. The range between the top entries in
189 * the two prioqs is the time window we can freely schedule
190 * wakeups in */
191
192 Prioq *earliest;
193 Prioq *latest;
194 usec_t next;
195
196 bool_Bool needs_rearm:1;
197};
198
199struct signal_data {
200 WakeupType wakeup;
201
202 /* For each priority we maintain one signal fd, so that we
203 * only have to dequeue a single event per priority at a
204 * time. */
205
206 int fd;
207 int64_t priority;
208 sigset_t sigset;
209 sd_event_source *current;
210};
211
212/* A structure listing all event sources currently watching a specific inode */
213struct inode_data {
214 /* The identifier for the inode, the combination of the .st_dev + .st_ino fields of the file */
215 ino_t ino;
216 dev_t dev;
217
218 /* An fd of the inode to watch. The fd is kept open until the next iteration of the loop, so that we can
219 * rearrange the priority still until then, as we need the original inode to change the priority as we need to
220 * add a watch descriptor to the right inotify for the priority which we can only do if we have a handle to the
221 * original inode. We keep a list of all inode_data objects with an open fd in the to_close list (see below) of
222 * the sd-event object, so that it is efficient to close everything, before entering the next event loop
223 * iteration. */
224 int fd;
225
226 /* The inotify "watch descriptor" */
227 int wd;
228
229 /* The combination of the mask of all inotify watches on this inode we manage. This is also the mask that has
230 * most recently been set on the watch descriptor. */
231 uint32_t combined_mask;
232
233 /* All event sources subscribed to this inode */
234 LIST_HEAD(sd_event_source, event_sources)sd_event_source *event_sources;
235
236 /* The inotify object we watch this inode with */
237 struct inotify_data *inotify_data;
238
239 /* A linked list of all inode data objects with fds to close (see above) */
240 LIST_FIELDS(struct inode_data, to_close)struct inode_data *to_close_next, *to_close_prev;
241};
242
243/* A structure encapsulating an inotify fd */
244struct inotify_data {
245 WakeupType wakeup;
246
247 /* For each priority we maintain one inotify fd, so that we only have to dequeue a single event per priority at
248 * a time */
249
250 int fd;
251 int64_t priority;
252
253 Hashmap *inodes; /* The inode_data structures keyed by dev+ino */
254 Hashmap *wd; /* The inode_data structures keyed by the watch descriptor for each */
255
256 /* The buffer we read inotify events into */
257 union inotify_event_buffer buffer;
258 size_t buffer_filled; /* fill level of the buffer */
259
260 /* How many event sources are currently marked pending for this inotify. We won't read new events off the
261 * inotify fd as long as there are still pending events on the inotify (because we have no strategy of queuing
262 * the events locally if they can't be coalesced). */
263 unsigned n_pending;
264
265 /* A linked list of all inotify objects with data already read, that still need processing. We keep this list
266 * to make it efficient to figure out what inotify objects to process data on next. */
267 LIST_FIELDS(struct inotify_data, buffered)struct inotify_data *buffered_next, *buffered_prev;
268};
269
270struct sd_event {
271 unsigned n_ref;
272
273 int epoll_fd;
274 int watchdog_fd;
275
276 Prioq *pending;
277 Prioq *prepare;
278
279 /* timerfd_create() only supports these five clocks so far. We
280 * can add support for more clocks when the kernel learns to
281 * deal with them, too. */
282 struct clock_data realtime;
283 struct clock_data boottime;
284 struct clock_data monotonic;
285 struct clock_data realtime_alarm;
286 struct clock_data boottime_alarm;
287
288 usec_t perturb;
289
290 sd_event_source **signal_sources; /* indexed by signal number */
291 Hashmap *signal_data; /* indexed by priority */
292
293 Hashmap *child_sources;
294 unsigned n_online_child_sources;
295
296 Set *post_sources;
297
298 Prioq *exit;
299
300 Hashmap *inotify_data; /* indexed by priority */
301
302 /* A list of inode structures that still have an fd open, that we need to close before the next loop iteration */
303 LIST_HEAD(struct inode_data, inode_data_to_close)struct inode_data *inode_data_to_close;
304
305 /* A list of inotify objects that already have events buffered which aren't processed yet */
306 LIST_HEAD(struct inotify_data, inotify_data_buffered)struct inotify_data *inotify_data_buffered;
307
308 pid_t original_pid;
309
310 uint64_t iteration;
311 triple_timestamp timestamp;
312 int state;
313
314 bool_Bool exit_requested:1;
315 bool_Bool need_process_child:1;
316 bool_Bool watchdog:1;
317 bool_Bool profile_delays:1;
318
319 int exit_code;
320
321 pid_t tid;
322 sd_event **default_event_ptr;
323
324 usec_t watchdog_last, watchdog_period;
325
326 unsigned n_sources;
327
328 LIST_HEAD(sd_event_source, sources)sd_event_source *sources;
329
330 usec_t last_run_usec, last_log_usec;
331 unsigned delays[sizeof(usec_t) * 8];
332};
333
334static thread_local__thread sd_event *default_event = NULL((void*)0);
335
336static void source_disconnect(sd_event_source *s);
337static void event_gc_inode_data(sd_event *e, struct inode_data *d);
338
339static bool_Bool event_source_is_online(sd_event_source *s) {
340 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 340, __PRETTY_FUNCTION__); } while (0)
;
341 return s->enabled != SD_EVENT_OFF && !s->ratelimited;
342}
343
344static bool_Bool event_source_is_offline(sd_event_source *s) {
345 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 345, __PRETTY_FUNCTION__); } while (0)
;
346 return s->enabled == SD_EVENT_OFF || s->ratelimited;
347}
348
349static sd_event *event_resolve(sd_event *e) {
350 return e == SD_EVENT_DEFAULT((sd_event *) 1) ? default_event : e;
351}
352
353static int pending_prioq_compare(const void *a, const void *b) {
354 const sd_event_source *x = a, *y = b;
355 int r;
356
357 assert(x->pending)do { if ((__builtin_expect(!!(!(x->pending)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("x->pending"), "../src/libsystemd/sd-event/sd-event.c"
, 357, __PRETTY_FUNCTION__); } while (0)
;
358 assert(y->pending)do { if ((__builtin_expect(!!(!(y->pending)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("y->pending"), "../src/libsystemd/sd-event/sd-event.c"
, 358, __PRETTY_FUNCTION__); } while (0)
;
359
360 /* Enabled ones first */
361 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
362 return -1;
363 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
364 return 1;
365
366 /* Non rate-limited ones first. */
367 r = CMP(!!x->ratelimited, !!y->ratelimited)({ const typeof((!!x->ratelimited)) __unique_prefix_A41 = (
(!!x->ratelimited)); const typeof((!!y->ratelimited)) __unique_prefix_B42
= ((!!y->ratelimited)); __unique_prefix_A41 < __unique_prefix_B42
? -1 : __unique_prefix_A41 > __unique_prefix_B42 ? 1 : 0;
})
;
368 if (r != 0)
369 return r;
370
371 /* Lower priority values first */
372 r = CMP(x->priority, y->priority)({ const typeof((x->priority)) __unique_prefix_A43 = ((x->
priority)); const typeof((y->priority)) __unique_prefix_B44
= ((y->priority)); __unique_prefix_A43 < __unique_prefix_B44
? -1 : __unique_prefix_A43 > __unique_prefix_B44 ? 1 : 0;
})
;
373 if (r != 0)
374 return r;
375
376 /* Older entries first */
377 return CMP(x->pending_iteration, y->pending_iteration)({ const typeof((x->pending_iteration)) __unique_prefix_A45
= ((x->pending_iteration)); const typeof((y->pending_iteration
)) __unique_prefix_B46 = ((y->pending_iteration)); __unique_prefix_A45
< __unique_prefix_B46 ? -1 : __unique_prefix_A45 > __unique_prefix_B46
? 1 : 0; })
;
378}
379
380static int prepare_prioq_compare(const void *a, const void *b) {
381 const sd_event_source *x = a, *y = b;
382 int r;
383
384 assert(x->prepare)do { if ((__builtin_expect(!!(!(x->prepare)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("x->prepare"), "../src/libsystemd/sd-event/sd-event.c"
, 384, __PRETTY_FUNCTION__); } while (0)
;
385 assert(y->prepare)do { if ((__builtin_expect(!!(!(y->prepare)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("y->prepare"), "../src/libsystemd/sd-event/sd-event.c"
, 385, __PRETTY_FUNCTION__); } while (0)
;
386
387 /* Enabled ones first */
388 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
389 return -1;
390 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
391 return 1;
392
393 /* Non rate-limited ones first. */
394 r = CMP(!!x->ratelimited, !!y->ratelimited)({ const typeof((!!x->ratelimited)) __unique_prefix_A47 = (
(!!x->ratelimited)); const typeof((!!y->ratelimited)) __unique_prefix_B48
= ((!!y->ratelimited)); __unique_prefix_A47 < __unique_prefix_B48
? -1 : __unique_prefix_A47 > __unique_prefix_B48 ? 1 : 0;
})
;
395 if (r != 0)
396 return r;
397
398 /* Move most recently prepared ones last, so that we can stop
399 * preparing as soon as we hit one that has already been
400 * prepared in the current iteration */
401 r = CMP(x->prepare_iteration, y->prepare_iteration)({ const typeof((x->prepare_iteration)) __unique_prefix_A49
= ((x->prepare_iteration)); const typeof((y->prepare_iteration
)) __unique_prefix_B50 = ((y->prepare_iteration)); __unique_prefix_A49
< __unique_prefix_B50 ? -1 : __unique_prefix_A49 > __unique_prefix_B50
? 1 : 0; })
;
402 if (r != 0)
403 return r;
404
405 /* Lower priority values first */
406 return CMP(x->priority, y->priority)({ const typeof((x->priority)) __unique_prefix_A51 = ((x->
priority)); const typeof((y->priority)) __unique_prefix_B52
= ((y->priority)); __unique_prefix_A51 < __unique_prefix_B52
? -1 : __unique_prefix_A51 > __unique_prefix_B52 ? 1 : 0;
})
;
407}
408
409static usec_t time_event_source_next(const sd_event_source *s) {
410 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 410, __PRETTY_FUNCTION__); } while (0)
;
411
412 /* We have two kinds of event sources that have elapsation times associated with them: the actual
413 * time based ones and the ones for which a ratelimit can be in effect (where we want to be notified
414 * once the ratelimit time window ends). Let's return the next elapsing time depending on what we are
415 * looking at here. */
416
417 if (s->ratelimited) { /* If rate-limited the next elapsation is when the ratelimit time window ends */
418 assert(s->rate_limit.begin != 0)do { if ((__builtin_expect(!!(!(s->rate_limit.begin != 0))
,0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->rate_limit.begin != 0"
), "../src/libsystemd/sd-event/sd-event.c", 418, __PRETTY_FUNCTION__
); } while (0)
;
419 assert(s->rate_limit.interval != 0)do { if ((__builtin_expect(!!(!(s->rate_limit.interval != 0
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->rate_limit.interval != 0"
), "../src/libsystemd/sd-event/sd-event.c", 419, __PRETTY_FUNCTION__
); } while (0)
;
420 return usec_add(s->rate_limit.begin, s->rate_limit.interval);
421 }
422
423 /* Otherwise this must be a time event source, if not ratelimited */
424 if (EVENT_SOURCE_IS_TIME(s->type)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; })
)
425 return s->time.next;
426
427 return USEC_INFINITY((usec_t) -1);
428}
429
430static int earliest_time_prioq_compare(const void *a, const void *b) {
431 const sd_event_source *x = a, *y = b;
432
433 /* Enabled ones first */
434 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
435 return -1;
436 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
437 return 1;
438
439 /* Move the pending ones to the end */
440 if (!x->pending && y->pending)
441 return -1;
442 if (x->pending && !y->pending)
443 return 1;
444
445 /* Order by time */
446 return CMP(time_event_source_next(x), time_event_source_next(y))({ const typeof((time_event_source_next(x))) __unique_prefix_A53
= ((time_event_source_next(x))); const typeof((time_event_source_next
(y))) __unique_prefix_B54 = ((time_event_source_next(y))); __unique_prefix_A53
< __unique_prefix_B54 ? -1 : __unique_prefix_A53 > __unique_prefix_B54
? 1 : 0; })
;
447}
448
449static usec_t time_event_source_latest(const sd_event_source *s) {
450 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 450, __PRETTY_FUNCTION__); } while (0)
;
451
452 if (s->ratelimited) { /* For ratelimited stuff the earliest and the latest time shall actually be the
453 * same, as we should avoid adding additional inaccuracy on an inaccuracy time
454 * window */
455 assert(s->rate_limit.begin != 0)do { if ((__builtin_expect(!!(!(s->rate_limit.begin != 0))
,0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->rate_limit.begin != 0"
), "../src/libsystemd/sd-event/sd-event.c", 455, __PRETTY_FUNCTION__
); } while (0)
;
456 assert(s->rate_limit.interval != 0)do { if ((__builtin_expect(!!(!(s->rate_limit.interval != 0
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->rate_limit.interval != 0"
), "../src/libsystemd/sd-event/sd-event.c", 456, __PRETTY_FUNCTION__
); } while (0)
;
457 return usec_add(s->rate_limit.begin, s->rate_limit.interval);
458 }
459
460 /* Must be a time event source, if not ratelimited */
461 if (EVENT_SOURCE_IS_TIME(s->type)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; })
)
462 return usec_add(s->time.next, s->time.accuracy);
463
464 return USEC_INFINITY((usec_t) -1);
465}
466
467static int latest_time_prioq_compare(const void *a, const void *b) {
468 const sd_event_source *x = a, *y = b;
469
470 /* Enabled ones first */
471 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
472 return -1;
473 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
474 return 1;
475
476 /* Move the pending ones to the end */
477 if (!x->pending && y->pending)
478 return -1;
479 if (x->pending && !y->pending)
480 return 1;
481
482 /* Order by time */
483 if (time_event_source_latest(x) < time_event_source_latest(y))
484 return -1;
485 if (time_event_source_latest(x) > time_event_source_latest(y))
486 return 1;
487
488 return 0;
489}
490
491static int exit_prioq_compare(const void *a, const void *b) {
492 const sd_event_source *x = a, *y = b;
493
494 assert(x->type == SOURCE_EXIT)do { if ((__builtin_expect(!!(!(x->type == SOURCE_EXIT)),0
))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("x->type == SOURCE_EXIT"
), "../src/libsystemd/sd-event/sd-event.c", 494, __PRETTY_FUNCTION__
); } while (0)
;
495 assert(y->type == SOURCE_EXIT)do { if ((__builtin_expect(!!(!(y->type == SOURCE_EXIT)),0
))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("y->type == SOURCE_EXIT"
), "../src/libsystemd/sd-event/sd-event.c", 495, __PRETTY_FUNCTION__
); } while (0)
;
496
497 /* Enabled ones first */
498 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
499 return -1;
500 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
501 return 1;
502
503 /* Lower priority values first */
504 if (x->priority < y->priority)
505 return -1;
506 if (x->priority > y->priority)
507 return 1;
508
509 return 0;
510}
511
512static void free_clock_data(struct clock_data *d) {
513 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 513, __PRETTY_FUNCTION__); } while (0)
;
514 assert(d->wakeup == WAKEUP_CLOCK_DATA)do { if ((__builtin_expect(!!(!(d->wakeup == WAKEUP_CLOCK_DATA
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("d->wakeup == WAKEUP_CLOCK_DATA"
), "../src/libsystemd/sd-event/sd-event.c", 514, __PRETTY_FUNCTION__
); } while (0)
;
515
516 safe_close(d->fd);
517 prioq_free(d->earliest);
518 prioq_free(d->latest);
519}
520
521static void event_free(sd_event *e) {
522 sd_event_source *s;
523
524 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 524, __PRETTY_FUNCTION__); } while (0)
;
525
526 while ((s = e->sources)) {
527 assert(s->floating)do { if ((__builtin_expect(!!(!(s->floating)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s->floating"), "../src/libsystemd/sd-event/sd-event.c"
, 527, __PRETTY_FUNCTION__); } while (0)
;
528 source_disconnect(s);
529 sd_event_source_unref(s);
530 }
531
532 assert(e->n_sources == 0)do { if ((__builtin_expect(!!(!(e->n_sources == 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e->n_sources == 0"), "../src/libsystemd/sd-event/sd-event.c"
, 532, __PRETTY_FUNCTION__); } while (0)
;
533
534 if (e->default_event_ptr)
535 *(e->default_event_ptr) = NULL((void*)0);
536
537 safe_close(e->epoll_fd);
538 safe_close(e->watchdog_fd);
539
540 free_clock_data(&e->realtime);
541 free_clock_data(&e->boottime);
542 free_clock_data(&e->monotonic);
543 free_clock_data(&e->realtime_alarm);
544 free_clock_data(&e->boottime_alarm);
545
546 prioq_free(e->pending);
547 prioq_free(e->prepare);
548 prioq_free(e->exit);
549
550 free(e->signal_sources);
551 hashmap_free(e->signal_data);
552
553 hashmap_free(e->inotify_data);
554
555 hashmap_free(e->child_sources);
556 set_free(e->post_sources);
557 free(e);
558}
559
560_public___attribute__ ((visibility("default"))) int sd_event_new(sd_event** ret) {
561 sd_event *e;
562 int r;
563
564 assert_return(ret, -EINVAL)do { if (!(((__builtin_expect(!!(ret),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/libsystemd/sd-event/sd-event.c"
, 564, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
565
566 e = new(sd_event, 1)((sd_event*) malloc_multiply(sizeof(sd_event), (1)));
567 if (!e)
568 return -ENOMEM12;
569
570 *e = (sd_event) {
571 .n_ref = 1,
572 .epoll_fd = -1,
573 .watchdog_fd = -1,
574 .realtime.wakeup = WAKEUP_CLOCK_DATA,
575 .realtime.fd = -1,
576 .realtime.next = USEC_INFINITY((usec_t) -1),
577 .boottime.wakeup = WAKEUP_CLOCK_DATA,
578 .boottime.fd = -1,
579 .boottime.next = USEC_INFINITY((usec_t) -1),
580 .monotonic.wakeup = WAKEUP_CLOCK_DATA,
581 .monotonic.fd = -1,
582 .monotonic.next = USEC_INFINITY((usec_t) -1),
583 .realtime_alarm.wakeup = WAKEUP_CLOCK_DATA,
584 .realtime_alarm.fd = -1,
585 .realtime_alarm.next = USEC_INFINITY((usec_t) -1),
586 .boottime_alarm.wakeup = WAKEUP_CLOCK_DATA,
587 .boottime_alarm.fd = -1,
588 .boottime_alarm.next = USEC_INFINITY((usec_t) -1),
589 .perturb = USEC_INFINITY((usec_t) -1),
590 .original_pid = getpid_cached(),
591 };
592
593 r = prioq_ensure_allocated(&e->pending, pending_prioq_compare);
594 if (r < 0)
595 goto fail;
596
597 e->epoll_fd = epoll_create1(EPOLL_CLOEXECEPOLL_CLOEXEC);
598 if (e->epoll_fd < 0) {
599 r = -errno(*__errno_location ());
600 goto fail;
601 }
602
603 e->epoll_fd = fd_move_above_stdio(e->epoll_fd);
604
605 if (secure_getenv("SD_EVENT_PROFILE_DELAYS")) {
606 log_debug("Event loop profiling enabled. Logarithmic histogram of event loop iterations in the range 2^0 ... 2^63 us will be logged every 5s.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-event/sd-event.c", 606, __func__, "Event loop profiling enabled. Logarithmic histogram of event loop iterations in the range 2^0 ... 2^63 us will be logged every 5s."
) : -abs(_e); })
;
607 e->profile_delays = true1;
608 }
609
610 *ret = e;
611 return 0;
612
613fail:
614 event_free(e);
615 return r;
616}
617
618_public___attribute__ ((visibility("default"))) sd_event* sd_event_ref(sd_event *e) {
619
620 if (!e)
621 return NULL((void*)0);
622
623 assert(e->n_ref >= 1)do { if ((__builtin_expect(!!(!(e->n_ref >= 1)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e->n_ref >= 1"), "../src/libsystemd/sd-event/sd-event.c"
, 623, __PRETTY_FUNCTION__); } while (0)
;
624 e->n_ref++;
625
626 return e;
627}
628
629_public___attribute__ ((visibility("default"))) sd_event* sd_event_unref(sd_event *e) {
630
631 if (!e)
632 return NULL((void*)0);
633
634 assert(e->n_ref >= 1)do { if ((__builtin_expect(!!(!(e->n_ref >= 1)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e->n_ref >= 1"), "../src/libsystemd/sd-event/sd-event.c"
, 634, __PRETTY_FUNCTION__); } while (0)
;
635 e->n_ref--;
636
637 if (e->n_ref <= 0)
638 event_free(e);
639
640 return NULL((void*)0);
641}
642
643_public___attribute__ ((visibility("default"))) sd_event_source* sd_event_source_disable_unref(sd_event_source *s) {
644 if (s)
645 (void) sd_event_source_set_enabled(s, SD_EVENT_OFF);
646 return sd_event_source_unref(s);
647}
648
649static bool_Bool event_pid_changed(sd_event *e) {
650 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 650, __PRETTY_FUNCTION__); } while (0)
;
651
652 /* We don't support people creating an event loop and keeping
653 * it around over a fork(). Let's complain. */
654
655 return e->original_pid != getpid_cached();
656}
657
658static void source_io_unregister(sd_event_source *s) {
659 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 659, __PRETTY_FUNCTION__); } while (0)
;
660 assert(s->type == SOURCE_IO)do { if ((__builtin_expect(!!(!(s->type == SOURCE_IO)),0))
) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->type == SOURCE_IO"
), "../src/libsystemd/sd-event/sd-event.c", 660, __PRETTY_FUNCTION__
); } while (0)
;
661
662 if (event_pid_changed(s->event))
663 return;
664
665 if (!s->io.registered)
666 return;
667
668 if (epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL2, s->io.fd, NULL((void*)0)) < 0)
669 log_debug_errno(errno, "Failed to remove source %s (type %s) from epoll, ignoring: %m",({ int _level = ((7)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/libsystemd/sd-event/sd-event.c",
670, __func__, "Failed to remove source %s (type %s) from epoll, ignoring: %m"
, strna(s->description), event_source_type_to_string(s->
type)) : -abs(_e); })
670 strna(s->description), event_source_type_to_string(s->type))({ int _level = ((7)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/libsystemd/sd-event/sd-event.c",
670, __func__, "Failed to remove source %s (type %s) from epoll, ignoring: %m"
, strna(s->description), event_source_type_to_string(s->
type)) : -abs(_e); })
;
671
672 s->io.registered = false0;
673}
674
675static int source_io_register(
676 sd_event_source *s,
677 int enabled,
678 uint32_t events) {
679
680 struct epoll_event ev;
681 int r;
682
683 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 683, __PRETTY_FUNCTION__); } while (0)
;
684 assert(s->type == SOURCE_IO)do { if ((__builtin_expect(!!(!(s->type == SOURCE_IO)),0))
) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->type == SOURCE_IO"
), "../src/libsystemd/sd-event/sd-event.c", 684, __PRETTY_FUNCTION__
); } while (0)
;
685 assert(enabled != SD_EVENT_OFF)do { if ((__builtin_expect(!!(!(enabled != SD_EVENT_OFF)),0))
) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("enabled != SD_EVENT_OFF"
), "../src/libsystemd/sd-event/sd-event.c", 685, __PRETTY_FUNCTION__
); } while (0)
;
686
687 ev = (struct epoll_event) {
688 .events = events | (enabled == SD_EVENT_ONESHOT ? EPOLLONESHOTEPOLLONESHOT : 0),
689 .data.ptr = s,
690 };
691
692 if (s->io.registered)
693 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_MOD3, s->io.fd, &ev);
694 else
695 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_ADD1, s->io.fd, &ev);
696 if (r < 0)
697 return -errno(*__errno_location ());
698
699 s->io.registered = true1;
700
701 return 0;
702}
703
704static clockid_t event_source_type_to_clock(EventSourceType t) {
705
706 switch (t) {
707
708 case SOURCE_TIME_REALTIME:
709 return CLOCK_REALTIME0;
710
711 case SOURCE_TIME_BOOTTIME:
712 return CLOCK_BOOTTIME7;
713
714 case SOURCE_TIME_MONOTONIC:
715 return CLOCK_MONOTONIC1;
716
717 case SOURCE_TIME_REALTIME_ALARM:
718 return CLOCK_REALTIME_ALARM8;
719
720 case SOURCE_TIME_BOOTTIME_ALARM:
721 return CLOCK_BOOTTIME_ALARM9;
722
723 default:
724 return (clockid_t) -1;
725 }
726}
727
728static EventSourceType clock_to_event_source_type(clockid_t clock) {
729
730 switch (clock) {
731
732 case CLOCK_REALTIME0:
733 return SOURCE_TIME_REALTIME;
734
735 case CLOCK_BOOTTIME7:
736 return SOURCE_TIME_BOOTTIME;
737
738 case CLOCK_MONOTONIC1:
739 return SOURCE_TIME_MONOTONIC;
740
741 case CLOCK_REALTIME_ALARM8:
742 return SOURCE_TIME_REALTIME_ALARM;
743
744 case CLOCK_BOOTTIME_ALARM9:
745 return SOURCE_TIME_BOOTTIME_ALARM;
746
747 default:
748 return _SOURCE_EVENT_SOURCE_TYPE_INVALID;
749 }
750}
751
752static struct clock_data* event_get_clock_data(sd_event *e, EventSourceType t) {
753 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 753, __PRETTY_FUNCTION__); } while (0)
;
754
755 switch (t) {
756
757 case SOURCE_TIME_REALTIME:
758 return &e->realtime;
759
760 case SOURCE_TIME_BOOTTIME:
761 return &e->boottime;
762
763 case SOURCE_TIME_MONOTONIC:
764 return &e->monotonic;
765
766 case SOURCE_TIME_REALTIME_ALARM:
767 return &e->realtime_alarm;
768
769 case SOURCE_TIME_BOOTTIME_ALARM:
770 return &e->boottime_alarm;
771
772 default:
773 return NULL((void*)0);
774 }
775}
776
777static int event_make_signal_data(
778 sd_event *e,
779 int sig,
780 struct signal_data **ret) {
781
782 struct epoll_event ev;
783 struct signal_data *d;
784 bool_Bool added = false0;
785 sigset_t ss_copy;
786 int64_t priority;
787 int r;
788
789 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 789, __PRETTY_FUNCTION__); } while (0)
;
790
791 if (event_pid_changed(e))
792 return -ECHILD10;
793
794 if (e->signal_sources && e->signal_sources[sig])
795 priority = e->signal_sources[sig]->priority;
796 else
797 priority = SD_EVENT_PRIORITY_NORMAL;
798
799 d = hashmap_get(e->signal_data, &priority);
800 if (d) {
801 if (sigismember(&d->sigset, sig) > 0) {
802 if (ret)
803 *ret = d;
804 return 0;
805 }
806 } else {
807 r = hashmap_ensure_allocated(&e->signal_data, &uint64_hash_ops)internal_hashmap_ensure_allocated(&e->signal_data, &
uint64_hash_ops )
;
808 if (r < 0)
809 return r;
810
811 d = new(struct signal_data, 1)((struct signal_data*) malloc_multiply(sizeof(struct signal_data
), (1)))
;
812 if (!d)
813 return -ENOMEM12;
814
815 *d = (struct signal_data) {
816 .wakeup = WAKEUP_SIGNAL_DATA,
817 .fd = -1,
818 .priority = priority,
819 };
820
821 r = hashmap_put(e->signal_data, &d->priority, d);
822 if (r < 0) {
823 free(d);
824 return r;
825 }
826
827 added = true1;
828 }
829
830 ss_copy = d->sigset;
831 assert_se(sigaddset(&ss_copy, sig) >= 0)do { if ((__builtin_expect(!!(!(sigaddset(&ss_copy, sig) >=
0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("sigaddset(&ss_copy, sig) >= 0"
), "../src/libsystemd/sd-event/sd-event.c", 831, __PRETTY_FUNCTION__
); } while (0)
;
832
833 r = signalfd(d->fd, &ss_copy, SFD_NONBLOCKSFD_NONBLOCK|SFD_CLOEXECSFD_CLOEXEC);
834 if (r < 0) {
835 r = -errno(*__errno_location ());
836 goto fail;
837 }
838
839 d->sigset = ss_copy;
840
841 if (d->fd >= 0) {
842 if (ret)
843 *ret = d;
844 return 0;
845 }
846
847 d->fd = fd_move_above_stdio(r);
848
849 ev = (struct epoll_event) {
850 .events = EPOLLINEPOLLIN,
851 .data.ptr = d,
852 };
853
854 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD1, d->fd, &ev);
855 if (r < 0) {
856 r = -errno(*__errno_location ());
857 goto fail;
858 }
859
860 if (ret)
861 *ret = d;
862
863 return 0;
864
865fail:
866 if (added) {
867 d->fd = safe_close(d->fd);
868 hashmap_remove(e->signal_data, &d->priority);
869 free(d);
870 }
871
872 return r;
873}
874
875static void event_unmask_signal_data(sd_event *e, struct signal_data *d, int sig) {
876 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 876, __PRETTY_FUNCTION__); } while (0)
;
877 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 877, __PRETTY_FUNCTION__); } while (0)
;
878
879 /* Turns off the specified signal in the signal data
880 * object. If the signal mask of the object becomes empty that
881 * way removes it. */
882
883 if (sigismember(&d->sigset, sig) == 0)
884 return;
885
886 assert_se(sigdelset(&d->sigset, sig) >= 0)do { if ((__builtin_expect(!!(!(sigdelset(&d->sigset, sig
) >= 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, (
"sigdelset(&d->sigset, sig) >= 0"), "../src/libsystemd/sd-event/sd-event.c"
, 886, __PRETTY_FUNCTION__); } while (0)
;
887
888 if (sigisemptyset(&d->sigset)) {
889
890 /* If all the mask is all-zero we can get rid of the structure */
891 hashmap_remove(e->signal_data, &d->priority);
892 safe_close(d->fd);
893 free(d);
894 return;
895 }
896
897 assert(d->fd >= 0)do { if ((__builtin_expect(!!(!(d->fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d->fd >= 0"), "../src/libsystemd/sd-event/sd-event.c"
, 897, __PRETTY_FUNCTION__); } while (0)
;
898
899 if (signalfd(d->fd, &d->sigset, SFD_NONBLOCKSFD_NONBLOCK|SFD_CLOEXECSFD_CLOEXEC) < 0)
900 log_debug_errno(errno, "Failed to unset signal bit, ignoring: %m")({ int _level = ((7)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/libsystemd/sd-event/sd-event.c",
900, __func__, "Failed to unset signal bit, ignoring: %m") :
-abs(_e); })
;
901}
902
903static void event_gc_signal_data(sd_event *e, const int64_t *priority, int sig) {
904 struct signal_data *d;
905 static const int64_t zero_priority = 0;
906
907 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 907, __PRETTY_FUNCTION__); } while (0)
;
908
909 /* Rechecks if the specified signal is still something we are
910 * interested in. If not, we'll unmask it, and possibly drop
911 * the signalfd for it. */
912
913 if (sig == SIGCHLD17 &&
914 e->n_online_child_sources > 0)
915 return;
916
917 if (e->signal_sources &&
918 e->signal_sources[sig] &&
919 event_source_is_online(e->signal_sources[sig]))
920 return;
921
922 /*
923 * The specified signal might be enabled in three different queues:
924 *
925 * 1) the one that belongs to the priority passed (if it is non-NULL)
926 * 2) the one that belongs to the priority of the event source of the signal (if there is one)
927 * 3) the 0 priority (to cover the SIGCHLD case)
928 *
929 * Hence, let's remove it from all three here.
930 */
931
932 if (priority) {
933 d = hashmap_get(e->signal_data, priority);
934 if (d)
935 event_unmask_signal_data(e, d, sig);
936 }
937
938 if (e->signal_sources && e->signal_sources[sig]) {
939 d = hashmap_get(e->signal_data, &e->signal_sources[sig]->priority);
940 if (d)
941 event_unmask_signal_data(e, d, sig);
942 }
943
944 d = hashmap_get(e->signal_data, &zero_priority);
945 if (d)
946 event_unmask_signal_data(e, d, sig);
947}
948
949static void event_source_pp_prioq_reshuffle(sd_event_source *s) {
950 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 950, __PRETTY_FUNCTION__); } while (0)
;
951
952 /* Reshuffles the pending + prepare prioqs. Called whenever the dispatch order changes, i.e. when
953 * they are enabled/disabled or marked pending and such. */
954
955 if (s->pending)
956 prioq_reshuffle(s->event->pending, s, &s->pending_index);
957
958 if (s->prepare)
959 prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
960}
961
962static void event_source_time_prioq_reshuffle(sd_event_source *s) {
963 struct clock_data *d;
964
965 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 965, __PRETTY_FUNCTION__); } while (0)
;
966
967 /* Called whenever the event source's timer ordering properties changed, i.e. time, accuracy,
968 * pending, enable state. Makes sure the two prioq's are ordered properly again. */
969
970 if (s->ratelimited)
971 d = &s->event->monotonic;
972 else {
973 assert(EVENT_SOURCE_IS_TIME(s->type))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME,
SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; }))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("EVENT_SOURCE_IS_TIME(s->type)"), "../src/libsystemd/sd-event/sd-event.c"
, 973, __PRETTY_FUNCTION__); } while (0)
;
974 assert_se(d = event_get_clock_data(s->event, s->type))do { if ((__builtin_expect(!!(!(d = event_get_clock_data(s->
event, s->type))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("d = event_get_clock_data(s->event, s->type)"), "../src/libsystemd/sd-event/sd-event.c"
, 974, __PRETTY_FUNCTION__); } while (0)
;
975 }
976
977 prioq_reshuffle(d->earliest, s, &s->earliest_index);
978 prioq_reshuffle(d->latest, s, &s->latest_index);
979 d->needs_rearm = true1;
980}
981
982static void event_source_time_prioq_remove(
983 sd_event_source *s,
984 struct clock_data *d) {
985
986 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 986, __PRETTY_FUNCTION__); } while (0)
;
987 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 987, __PRETTY_FUNCTION__); } while (0)
;
988
989 prioq_remove(d->earliest, s, &s->earliest_index);
990 prioq_remove(d->latest, s, &s->latest_index);
991 s->earliest_index = s->latest_index = PRIOQ_IDX_NULL((unsigned) -1);
992 d->needs_rearm = true1;
993}
994
995static void source_disconnect(sd_event_source *s) {
996 sd_event *event;
997
998 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 998, __PRETTY_FUNCTION__); } while (0)
;
999
1000 if (!s->event)
1001 return;
1002
1003 assert(s->event->n_sources > 0)do { if ((__builtin_expect(!!(!(s->event->n_sources >
0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->event->n_sources > 0"
), "../src/libsystemd/sd-event/sd-event.c", 1003, __PRETTY_FUNCTION__
); } while (0)
;
1004
1005 switch (s->type) {
1006
1007 case SOURCE_IO:
1008 if (s->io.fd >= 0)
1009 source_io_unregister(s);
1010
1011 break;
1012
1013 case SOURCE_TIME_REALTIME:
1014 case SOURCE_TIME_BOOTTIME:
1015 case SOURCE_TIME_MONOTONIC:
1016 case SOURCE_TIME_REALTIME_ALARM:
1017 case SOURCE_TIME_BOOTTIME_ALARM:
1018 /* Only remove this event source from the time event source here if it is not ratelimited. If
1019 * it is ratelimited, we'll remove it below, separately. Why? Because the clock used might
1020 * differ: ratelimiting always uses CLOCK_MONOTONIC, but timer events might use any clock */
1021
1022 if (!s->ratelimited) {
1023 struct clock_data *d;
1024 assert_se(d = event_get_clock_data(s->event, s->type))do { if ((__builtin_expect(!!(!(d = event_get_clock_data(s->
event, s->type))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("d = event_get_clock_data(s->event, s->type)"), "../src/libsystemd/sd-event/sd-event.c"
, 1024, __PRETTY_FUNCTION__); } while (0)
;
1025 event_source_time_prioq_remove(s, d);
1026 }
1027
1028 break;
1029
1030 case SOURCE_SIGNAL:
1031 if (s->signal.sig > 0) {
1032
1033 if (s->event->signal_sources)
1034 s->event->signal_sources[s->signal.sig] = NULL((void*)0);
1035
1036 event_gc_signal_data(s->event, &s->priority, s->signal.sig);
1037 }
1038
1039 break;
1040
1041 case SOURCE_CHILD:
1042 if (s->child.pid > 0) {
1043 if (event_source_is_online(s)) {
1044 assert(s->event->n_online_child_sources > 0)do { if ((__builtin_expect(!!(!(s->event->n_online_child_sources
> 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->event->n_online_child_sources > 0"
), "../src/libsystemd/sd-event/sd-event.c", 1044, __PRETTY_FUNCTION__
); } while (0)
;
1045 s->event->n_online_child_sources--;
1046 }
1047
1048 (void) hashmap_remove(s->event->child_sources, PID_TO_PTR(s->child.pid));
1049 event_gc_signal_data(s->event, &s->priority, SIGCHLD17);
1050 }
1051
1052 break;
1053
1054 case SOURCE_DEFER:
1055 /* nothing */
1056 break;
1057
1058 case SOURCE_POST:
1059 set_remove(s->event->post_sources, s);
1060 break;
1061
1062 case SOURCE_EXIT:
1063 prioq_remove(s->event->exit, s, &s->exit.prioq_index);
1064 break;
1065
1066 case SOURCE_INOTIFY: {
1067 struct inode_data *inode_data;
1068
1069 inode_data = s->inotify.inode_data;
1070 if (inode_data) {
1071 struct inotify_data *inotify_data;
1072 assert_se(inotify_data = inode_data->inotify_data)do { if ((__builtin_expect(!!(!(inotify_data = inode_data->
inotify_data)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("inotify_data = inode_data->inotify_data"), "../src/libsystemd/sd-event/sd-event.c"
, 1072, __PRETTY_FUNCTION__); } while (0)
;
1073
1074 /* Detach this event source from the inode object */
1075 LIST_REMOVE(inotify.by_inode_data, inode_data->event_sources, s)do { typeof(*(inode_data->event_sources)) **_head = &(
inode_data->event_sources), *_item = (s); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd/sd-event/sd-event.c", 1075, __PRETTY_FUNCTION__
); } while (0); if (_item->inotify.by_inode_data_next) _item
->inotify.by_inode_data_next->inotify.by_inode_data_prev
= _item->inotify.by_inode_data_prev; if (_item->inotify
.by_inode_data_prev) _item->inotify.by_inode_data_prev->
inotify.by_inode_data_next = _item->inotify.by_inode_data_next
; else { do { if ((__builtin_expect(!!(!(*_head == _item)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*_head == _item"
), "../src/libsystemd/sd-event/sd-event.c", 1075, __PRETTY_FUNCTION__
); } while (0); *_head = _item->inotify.by_inode_data_next
; } _item->inotify.by_inode_data_next = _item->inotify.
by_inode_data_prev = ((void*)0); } while (0)
;
1076 s->inotify.inode_data = NULL((void*)0);
1077
1078 if (s->pending) {
1079 assert(inotify_data->n_pending > 0)do { if ((__builtin_expect(!!(!(inotify_data->n_pending >
0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("inotify_data->n_pending > 0"
), "../src/libsystemd/sd-event/sd-event.c", 1079, __PRETTY_FUNCTION__
); } while (0)
;
1080 inotify_data->n_pending--;
1081 }
1082
1083 /* Note that we don't reduce the inotify mask for the watch descriptor here if the inode is
1084 * continued to being watched. That's because inotify doesn't really have an API for that: we
1085 * can only change watch masks with access to the original inode either by fd or by path. But
1086 * paths aren't stable, and keeping an O_PATH fd open all the time would mean wasting an fd
1087 * continously and keeping the mount busy which we can't really do. We could reconstruct the
1088 * original inode from /proc/self/fdinfo/$INOTIFY_FD (as all watch descriptors are listed
1089 * there), but given the need for open_by_handle_at() which is privileged and not universally
1090 * available this would be quite an incomplete solution. Hence we go the other way, leave the
1091 * mask set, even if it is not minimized now, and ignore all events we aren't interested in
1092 * anymore after reception. Yes, this sucks, but … Linux … */
1093
1094 /* Maybe release the inode data (and its inotify) */
1095 event_gc_inode_data(s->event, inode_data);
1096 }
1097
1098 break;
1099 }
1100
1101 default:
1102 assert_not_reached("Wut? I shouldn't exist.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Wut? I shouldn't exist."), "../src/libsystemd/sd-event/sd-event.c"
, 1102, __PRETTY_FUNCTION__); } while (0)
;
1103 }
1104
1105 if (s->pending)
1106 prioq_remove(s->event->pending, s, &s->pending_index);
1107
1108 if (s->prepare)
1109 prioq_remove(s->event->prepare, s, &s->prepare_index);
1110
1111 if (s->ratelimited)
1112 event_source_time_prioq_remove(s, &s->event->monotonic);
1113
1114 event = s->event;
1115
1116 s->type = _SOURCE_EVENT_SOURCE_TYPE_INVALID;
1117 s->event = NULL((void*)0);
1118 LIST_REMOVE(sources, event->sources, s)do { typeof(*(event->sources)) **_head = &(event->sources
), *_item = (s); do { if ((__builtin_expect(!!(!(_item)),0)))
log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item"), "../src/libsystemd/sd-event/sd-event.c"
, 1118, __PRETTY_FUNCTION__); } while (0); if (_item->sources_next
) _item->sources_next->sources_prev = _item->sources_prev
; if (_item->sources_prev) _item->sources_prev->sources_next
= _item->sources_next; else { do { if ((__builtin_expect(
!!(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("*_head == _item"), "../src/libsystemd/sd-event/sd-event.c"
, 1118, __PRETTY_FUNCTION__); } while (0); *_head = _item->
sources_next; } _item->sources_next = _item->sources_prev
= ((void*)0); } while (0)
;
1119 event->n_sources--;
1120
1121 if (!s->floating)
1122 sd_event_unref(event);
1123}
1124
1125static void source_free(sd_event_source *s) {
1126 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 1126, __PRETTY_FUNCTION__); } while (0)
;
1127
1128 source_disconnect(s);
1129
1130 if (s->type == SOURCE_IO && s->io.owned)
1131 s->io.fd = safe_close(s->io.fd);
1132
1133 if (s->destroy_callback)
1134 s->destroy_callback(s->userdata);
1135
1136 free(s->description);
1137 free(s);
1138}
1139
1140static int source_set_pending(sd_event_source *s, bool_Bool b) {
1141 int r;
1142
1143 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 1143, __PRETTY_FUNCTION__); } while (0)
;
1144 assert(s->type != SOURCE_EXIT)do { if ((__builtin_expect(!!(!(s->type != SOURCE_EXIT)),0
))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->type != SOURCE_EXIT"
), "../src/libsystemd/sd-event/sd-event.c", 1144, __PRETTY_FUNCTION__
); } while (0)
;
1145
1146 if (s->pending == b)
1147 return 0;
1148
1149 s->pending = b;
1150
1151 if (b) {
1152 s->pending_iteration = s->event->iteration;
1153
1154 r = prioq_put(s->event->pending, s, &s->pending_index);
1155 if (r < 0) {
1156 s->pending = false0;
1157 return r;
1158 }
1159 } else
1160 assert_se(prioq_remove(s->event->pending, s, &s->pending_index))do { if ((__builtin_expect(!!(!(prioq_remove(s->event->
pending, s, &s->pending_index))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("prioq_remove(s->event->pending, s, &s->pending_index)"
), "../src/libsystemd/sd-event/sd-event.c", 1160, __PRETTY_FUNCTION__
); } while (0)
;
1161
1162 if (EVENT_SOURCE_IS_TIME(s->type)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; })
)
1163 event_source_time_prioq_reshuffle(s);
1164
1165 if (s->type == SOURCE_SIGNAL && !b) {
1166 struct signal_data *d;
1167
1168 d = hashmap_get(s->event->signal_data, &s->priority);
1169 if (d && d->current == s)
1170 d->current = NULL((void*)0);
1171 }
1172
1173 if (s->type == SOURCE_INOTIFY) {
1174
1175 assert(s->inotify.inode_data)do { if ((__builtin_expect(!!(!(s->inotify.inode_data)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->inotify.inode_data"
), "../src/libsystemd/sd-event/sd-event.c", 1175, __PRETTY_FUNCTION__
); } while (0)
;
1176 assert(s->inotify.inode_data->inotify_data)do { if ((__builtin_expect(!!(!(s->inotify.inode_data->
inotify_data)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("s->inotify.inode_data->inotify_data"), "../src/libsystemd/sd-event/sd-event.c"
, 1176, __PRETTY_FUNCTION__); } while (0)
;
1177
1178 if (b)
1179 s->inotify.inode_data->inotify_data->n_pending ++;
1180 else {
1181 assert(s->inotify.inode_data->inotify_data->n_pending > 0)do { if ((__builtin_expect(!!(!(s->inotify.inode_data->
inotify_data->n_pending > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s->inotify.inode_data->inotify_data->n_pending > 0"
), "../src/libsystemd/sd-event/sd-event.c", 1181, __PRETTY_FUNCTION__
); } while (0)
;
1182 s->inotify.inode_data->inotify_data->n_pending --;
1183 }
1184 }
1185
1186 return 0;
1187}
1188
1189static sd_event_source *source_new(sd_event *e, bool_Bool floating, EventSourceType type) {
1190 sd_event_source *s;
1191
1192 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1192, __PRETTY_FUNCTION__); } while (0)
;
1193
1194 s = new(sd_event_source, 1)((sd_event_source*) malloc_multiply(sizeof(sd_event_source), (
1)))
;
1195 if (!s)
1196 return NULL((void*)0);
1197
1198 *s = (struct sd_event_source) {
1199 .n_ref = 1,
1200 .event = e,
1201 .floating = floating,
1202 .type = type,
1203 .pending_index = PRIOQ_IDX_NULL((unsigned) -1),
1204 .prepare_index = PRIOQ_IDX_NULL((unsigned) -1),
1205 };
1206
1207 if (!floating)
1208 sd_event_ref(e);
1209
1210 LIST_PREPEND(sources, e->sources, s)do { typeof(*(e->sources)) **_head = &(e->sources),
*_item = (s); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_item"), "../src/libsystemd/sd-event/sd-event.c"
, 1210, __PRETTY_FUNCTION__); } while (0); if ((_item->sources_next
= *_head)) _item->sources_next->sources_prev = _item; _item
->sources_prev = ((void*)0); *_head = _item; } while (0)
;
1211 e->n_sources++;
1212
1213 return s;
1214}
1215
1216_public___attribute__ ((visibility("default"))) int sd_event_add_io(
1217 sd_event *e,
1218 sd_event_source **ret,
1219 int fd,
1220 uint32_t events,
1221 sd_event_io_handler_t callback,
1222 void *userdata) {
1223
1224 sd_event_source *s;
1225 int r;
1226
1227 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1227, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1228 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1228, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
1229 assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/libsystemd/sd-event/sd-event.c"
, 1229, __PRETTY_FUNCTION__), 0))) return (-9); } while (0)
;
1230 assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL)do { if (!(((__builtin_expect(!!(!(events & ~(EPOLLIN|EPOLLOUT
|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET))),1))) ? (1) :
(log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET))"
), "../src/libsystemd/sd-event/sd-event.c", 1230, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
1231 assert_return(callback, -EINVAL)do { if (!(((__builtin_expect(!!(callback),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("callback"), "../src/libsystemd/sd-event/sd-event.c"
, 1231, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1232 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 1232, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
1233 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1233, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
1234
1235 s = source_new(e, !ret, SOURCE_IO);
1236 if (!s)
1237 return -ENOMEM12;
1238
1239 s->wakeup = WAKEUP_EVENT_SOURCE;
1240 s->io.fd = fd;
1241 s->io.events = events;
1242 s->io.callback = callback;
1243 s->userdata = userdata;
1244 s->enabled = SD_EVENT_ON;
1245
1246 r = source_io_register(s, s->enabled, events);
1247 if (r < 0) {
1248 source_free(s);
1249 return r;
1250 }
1251
1252 if (ret)
1253 *ret = s;
1254
1255 return 0;
1256}
1257
1258static void initialize_perturb(sd_event *e) {
1259 sd_id128_t bootid = {};
1260
1261 /* When we sleep for longer, we try to realign the wakeup to
1262 the same time wihtin each minute/second/250ms, so that
1263 events all across the system can be coalesced into a single
1264 CPU wakeup. However, let's take some system-specific
1265 randomness for this value, so that in a network of systems
1266 with synced clocks timer events are distributed a
1267 bit. Here, we calculate a perturbation usec offset from the
1268 boot ID. */
1269
1270 if (_likely_(e->perturb != USEC_INFINITY)(__builtin_expect(!!(e->perturb != ((usec_t) -1)),1)))
1271 return;
1272
1273 if (sd_id128_get_boot(&bootid) >= 0)
1274 e->perturb = (bootid.qwords[0] ^ bootid.qwords[1]) % USEC_PER_MINUTE((usec_t) (60ULL*((usec_t) 1000000ULL)));
1275}
1276
1277static int event_setup_timer_fd(
1278 sd_event *e,
1279 struct clock_data *d,
1280 clockid_t clock) {
1281
1282 struct epoll_event ev;
1283 int r, fd;
1284
1285 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1285, __PRETTY_FUNCTION__); } while (0)
;
1286 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 1286, __PRETTY_FUNCTION__); } while (0)
;
1287
1288 if (_likely_(d->fd >= 0)(__builtin_expect(!!(d->fd >= 0),1)))
1289 return 0;
1290
1291 fd = timerfd_create(clock, TFD_NONBLOCKTFD_NONBLOCK|TFD_CLOEXECTFD_CLOEXEC);
1292 if (fd < 0)
1293 return -errno(*__errno_location ());
1294
1295 fd = fd_move_above_stdio(fd);
1296
1297 ev = (struct epoll_event) {
1298 .events = EPOLLINEPOLLIN,
1299 .data.ptr = d,
1300 };
1301
1302 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD1, fd, &ev);
1303 if (r < 0) {
1304 safe_close(fd);
1305 return -errno(*__errno_location ());
1306 }
1307
1308 d->fd = fd;
1309 return 0;
1310}
1311
1312static int time_exit_callback(sd_event_source *s, uint64_t usec, void *userdata) {
1313 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 1313, __PRETTY_FUNCTION__); } while (0)
;
1314
1315 return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata)((int) ((intptr_t) (userdata))));
1316}
1317
1318static int setup_clock_data(sd_event *e, struct clock_data *d, clockid_t clock) {
1319 int r;
1320
1321 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 1321, __PRETTY_FUNCTION__); } while (0)
;
1322
1323 if (d->fd < 0) {
1324 r = event_setup_timer_fd(e, d, clock);
1325 if (r < 0)
1326 return r;
1327 }
1328
1329 r = prioq_ensure_allocated(&d->earliest, earliest_time_prioq_compare);
1330 if (r < 0)
1331 return r;
1332
1333 r = prioq_ensure_allocated(&d->latest, latest_time_prioq_compare);
1334 if (r < 0)
1335 return r;
1336
1337 return 0;
1338}
1339
1340static int event_source_time_prioq_put(
1341 sd_event_source *s,
1342 struct clock_data *d) {
1343
1344 int r;
1345
1346 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 1346, __PRETTY_FUNCTION__); } while (0)
;
1347 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 1347, __PRETTY_FUNCTION__); } while (0)
;
1348
1349 r = prioq_put(d->earliest, s, &s->earliest_index);
1350 if (r < 0)
1351 return r;
1352
1353 r = prioq_put(d->latest, s, &s->latest_index);
1354 if (r < 0) {
1355 assert_se(prioq_remove(d->earliest, s, &s->earliest_index) > 0)do { if ((__builtin_expect(!!(!(prioq_remove(d->earliest, s
, &s->earliest_index) > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("prioq_remove(d->earliest, s, &s->earliest_index) > 0"
), "../src/libsystemd/sd-event/sd-event.c", 1355, __PRETTY_FUNCTION__
); } while (0)
;
1356 s->earliest_index = PRIOQ_IDX_NULL((unsigned) -1);
1357 return r;
1358 }
1359
1360 d->needs_rearm = true1;
1361 return 0;
1362}
1363
1364_public___attribute__ ((visibility("default"))) int sd_event_add_time(
1365 sd_event *e,
1366 sd_event_source **ret,
1367 clockid_t clock,
1368 uint64_t usec,
1369 uint64_t accuracy,
1370 sd_event_time_handler_t callback,
1371 void *userdata) {
1372
1373 EventSourceType type;
1374 sd_event_source *s;
1375 struct clock_data *d;
1376 int r;
1377
1378 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1378, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1379 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1379, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
1380 assert_return(accuracy != (uint64_t) -1, -EINVAL)do { if (!(((__builtin_expect(!!(accuracy != (uint64_t) -1),1
))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("accuracy != (uint64_t) -1"), "../src/libsystemd/sd-event/sd-event.c"
, 1380, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1381 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 1381, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
1382 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1382, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
1383
1384 if (!clock_supported(clock)) /* Checks whether the kernel supports the clock */
1385 return -EOPNOTSUPP95;
1386
1387 type = clock_to_event_source_type(clock); /* checks whether sd-event supports this clock */
1388 if (type < 0)
1389 return -EOPNOTSUPP95;
1390
1391 if (!callback)
1392 callback = time_exit_callback;
1393
1394 assert_se(d = event_get_clock_data(e, type))do { if ((__builtin_expect(!!(!(d = event_get_clock_data(e, type
))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("d = event_get_clock_data(e, type)"
), "../src/libsystemd/sd-event/sd-event.c", 1394, __PRETTY_FUNCTION__
); } while (0)
;
1395
1396 r = setup_clock_data(e, d, clock);
1397 if (r < 0)
1398 return r;
1399
1400 s = source_new(e, !ret, type);
1401 if (!s)
1402 return -ENOMEM12;
1403
1404 s->time.next = usec;
1405 s->time.accuracy = accuracy == 0 ? DEFAULT_ACCURACY_USEC(250 * ((usec_t) 1000ULL)) : accuracy;
1406 s->time.callback = callback;
1407 s->earliest_index = s->latest_index = PRIOQ_IDX_NULL((unsigned) -1);
1408 s->userdata = userdata;
1409 s->enabled = SD_EVENT_ONESHOT;
1410
1411 r = event_source_time_prioq_put(s, d);
1412 if (r < 0)
1413 goto fail;
1414
1415 if (ret)
1416 *ret = s;
1417
1418 return 0;
1419
1420fail:
1421 source_free(s);
1422 return r;
1423}
1424
1425static int signal_exit_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
1426 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 1426, __PRETTY_FUNCTION__); } while (0)
;
1427
1428 return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata)((int) ((intptr_t) (userdata))));
1429}
1430
1431_public___attribute__ ((visibility("default"))) int sd_event_add_signal(
1432 sd_event *e,
1433 sd_event_source **ret,
1434 int sig,
1435 sd_event_signal_handler_t callback,
1436 void *userdata) {
1437
1438 sd_event_source *s;
1439 struct signal_data *d;
1440 sigset_t ss;
1441 int r;
1442
1443 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1443, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1444 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1444, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
1445 assert_return(SIGNAL_VALID(sig), -EINVAL)do { if (!(((__builtin_expect(!!(SIGNAL_VALID(sig)),1))) ? (1
) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("SIGNAL_VALID(sig)"
), "../src/libsystemd/sd-event/sd-event.c", 1445, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
1446 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 1446, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
1447 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1447, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
1448
1449 if (!callback)
1450 callback = signal_exit_callback;
1451
1452 r = pthread_sigmask(SIG_SETMASK2, NULL((void*)0), &ss);
1453 if (r != 0)
1454 return -r;
1455
1456 if (!sigismember(&ss, sig))
1457 return -EBUSY16;
1458
1459 if (!e->signal_sources) {
1460 e->signal_sources = new0(sd_event_source*, _NSIG)((sd_event_source**) calloc(((64 + 1)), sizeof(sd_event_source
*)))
;
1461 if (!e->signal_sources)
1462 return -ENOMEM12;
1463 } else if (e->signal_sources[sig])
1464 return -EBUSY16;
1465
1466 s = source_new(e, !ret, SOURCE_SIGNAL);
1467 if (!s)
1468 return -ENOMEM12;
1469
1470 s->signal.sig = sig;
1471 s->signal.callback = callback;
1472 s->userdata = userdata;
1473 s->enabled = SD_EVENT_ON;
1474
1475 e->signal_sources[sig] = s;
1476
1477 r = event_make_signal_data(e, sig, &d);
1478 if (r < 0) {
1479 source_free(s);
1480 return r;
1481 }
1482
1483 /* Use the signal name as description for the event source by default */
1484 (void) sd_event_source_set_description(s, signal_to_string(sig));
1485
1486 if (ret)
1487 *ret = s;
1488
1489 return 0;
1490}
1491
1492_public___attribute__ ((visibility("default"))) int sd_event_add_child(
1493 sd_event *e,
1494 sd_event_source **ret,
1495 pid_t pid,
1496 int options,
1497 sd_event_child_handler_t callback,
1498 void *userdata) {
1499
1500 sd_event_source *s;
1501 int r;
1502
1503 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1503, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1504 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1504, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
1505 assert_return(pid > 1, -EINVAL)do { if (!(((__builtin_expect(!!(pid > 1),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("pid > 1"), "../src/libsystemd/sd-event/sd-event.c"
, 1505, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1506 assert_return(!(options & ~(WEXITED|WSTOPPED|WCONTINUED)), -EINVAL)do { if (!(((__builtin_expect(!!(!(options & ~(4|2|8))),1
))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!(options & ~(WEXITED|WSTOPPED|WCONTINUED))"), "../src/libsystemd/sd-event/sd-event.c"
, 1506, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1507 assert_return(options != 0, -EINVAL)do { if (!(((__builtin_expect(!!(options != 0),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("options != 0"
), "../src/libsystemd/sd-event/sd-event.c", 1507, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
1508 assert_return(callback, -EINVAL)do { if (!(((__builtin_expect(!!(callback),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("callback"), "../src/libsystemd/sd-event/sd-event.c"
, 1508, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1509 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 1509, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
1510 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1510, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
1511
1512 r = hashmap_ensure_allocated(&e->child_sources, NULL)internal_hashmap_ensure_allocated(&e->child_sources, (
(void*)0) )
;
1513 if (r < 0)
1514 return r;
1515
1516 if (hashmap_contains(e->child_sources, PID_TO_PTR(pid)))
1517 return -EBUSY16;
1518
1519 s = source_new(e, !ret, SOURCE_CHILD);
1520 if (!s)
1521 return -ENOMEM12;
1522
1523 s->child.pid = pid;
1524 s->child.options = options;
1525 s->child.callback = callback;
1526 s->userdata = userdata;
1527 s->enabled = SD_EVENT_ONESHOT;
1528
1529 r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s);
1530 if (r < 0) {
1531 source_free(s);
1532 return r;
1533 }
1534
1535 e->n_online_child_sources++;
1536
1537 r = event_make_signal_data(e, SIGCHLD17, NULL((void*)0));
1538 if (r < 0) {
1539 e->n_online_child_sources--;
1540 source_free(s);
1541 return r;
1542 }
1543
1544 e->need_process_child = true1;
1545
1546 if (ret)
1547 *ret = s;
1548
1549 return 0;
1550}
1551
1552_public___attribute__ ((visibility("default"))) int sd_event_add_defer(
1553 sd_event *e,
1554 sd_event_source **ret,
1555 sd_event_handler_t callback,
1556 void *userdata) {
1557
1558 sd_event_source *s;
1559 int r;
1560
1561 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1561, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1562 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1562, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
1563 assert_return(callback, -EINVAL)do { if (!(((__builtin_expect(!!(callback),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("callback"), "../src/libsystemd/sd-event/sd-event.c"
, 1563, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1564 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 1564, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
1565 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1565, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
1566
1567 s = source_new(e, !ret, SOURCE_DEFER);
1568 if (!s)
1569 return -ENOMEM12;
1570
1571 s->defer.callback = callback;
1572 s->userdata = userdata;
1573 s->enabled = SD_EVENT_ONESHOT;
1574
1575 r = source_set_pending(s, true1);
1576 if (r < 0) {
1577 source_free(s);
1578 return r;
1579 }
1580
1581 if (ret)
1582 *ret = s;
1583
1584 return 0;
1585}
1586
1587_public___attribute__ ((visibility("default"))) int sd_event_add_post(
1588 sd_event *e,
1589 sd_event_source **ret,
1590 sd_event_handler_t callback,
1591 void *userdata) {
1592
1593 sd_event_source *s;
1594 int r;
1595
1596 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1596, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1597 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1597, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
1598 assert_return(callback, -EINVAL)do { if (!(((__builtin_expect(!!(callback),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("callback"), "../src/libsystemd/sd-event/sd-event.c"
, 1598, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1599 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 1599, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
1600 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1600, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
1601
1602 r = set_ensure_allocated(&e->post_sources, NULL)internal_set_ensure_allocated(&e->post_sources, ((void
*)0) )
;
1603 if (r < 0)
1604 return r;
1605
1606 s = source_new(e, !ret, SOURCE_POST);
1607 if (!s)
1608 return -ENOMEM12;
1609
1610 s->post.callback = callback;
1611 s->userdata = userdata;
1612 s->enabled = SD_EVENT_ON;
1613
1614 r = set_put(e->post_sources, s);
1615 if (r < 0) {
1616 source_free(s);
1617 return r;
1618 }
1619
1620 if (ret)
1621 *ret = s;
1622
1623 return 0;
1624}
1625
1626_public___attribute__ ((visibility("default"))) int sd_event_add_exit(
1627 sd_event *e,
1628 sd_event_source **ret,
1629 sd_event_handler_t callback,
1630 void *userdata) {
1631
1632 sd_event_source *s;
1633 int r;
1634
1635 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1635, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1636 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1636, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
1637 assert_return(callback, -EINVAL)do { if (!(((__builtin_expect(!!(callback),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("callback"), "../src/libsystemd/sd-event/sd-event.c"
, 1637, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1638 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 1638, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
1639 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1639, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
1640
1641 r = prioq_ensure_allocated(&e->exit, exit_prioq_compare);
1642 if (r < 0)
1643 return r;
1644
1645 s = source_new(e, !ret, SOURCE_EXIT);
1646 if (!s)
1647 return -ENOMEM12;
1648
1649 s->exit.callback = callback;
1650 s->userdata = userdata;
1651 s->exit.prioq_index = PRIOQ_IDX_NULL((unsigned) -1);
1652 s->enabled = SD_EVENT_ONESHOT;
1653
1654 r = prioq_put(s->event->exit, s, &s->exit.prioq_index);
1655 if (r < 0) {
1656 source_free(s);
1657 return r;
1658 }
1659
1660 if (ret)
1661 *ret = s;
1662
1663 return 0;
1664}
1665
1666static void event_free_inotify_data(sd_event *e, struct inotify_data *d) {
1667 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1667, __PRETTY_FUNCTION__); } while (0)
;
1668
1669 if (!d)
1670 return;
1671
1672 assert(hashmap_isempty(d->inodes))do { if ((__builtin_expect(!!(!(hashmap_isempty(d->inodes)
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("hashmap_isempty(d->inodes)"
), "../src/libsystemd/sd-event/sd-event.c", 1672, __PRETTY_FUNCTION__
); } while (0)
;
1673 assert(hashmap_isempty(d->wd))do { if ((__builtin_expect(!!(!(hashmap_isempty(d->wd))),0
))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("hashmap_isempty(d->wd)"
), "../src/libsystemd/sd-event/sd-event.c", 1673, __PRETTY_FUNCTION__
); } while (0)
;
1674
1675 if (d->buffer_filled > 0)
1676 LIST_REMOVE(buffered, e->inotify_data_buffered, d)do { typeof(*(e->inotify_data_buffered)) **_head = &(e
->inotify_data_buffered), *_item = (d); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd/sd-event/sd-event.c", 1676, __PRETTY_FUNCTION__
); } while (0); if (_item->buffered_next) _item->buffered_next
->buffered_prev = _item->buffered_prev; if (_item->buffered_prev
) _item->buffered_prev->buffered_next = _item->buffered_next
; else { do { if ((__builtin_expect(!!(!(*_head == _item)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*_head == _item"
), "../src/libsystemd/sd-event/sd-event.c", 1676, __PRETTY_FUNCTION__
); } while (0); *_head = _item->buffered_next; } _item->
buffered_next = _item->buffered_prev = ((void*)0); } while
(0)
;
1677
1678 hashmap_free(d->inodes);
1679 hashmap_free(d->wd);
1680
1681 assert_se(hashmap_remove(e->inotify_data, &d->priority) == d)do { if ((__builtin_expect(!!(!(hashmap_remove(e->inotify_data
, &d->priority) == d)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("hashmap_remove(e->inotify_data, &d->priority) == d"
), "../src/libsystemd/sd-event/sd-event.c", 1681, __PRETTY_FUNCTION__
); } while (0)
;
1682
1683 if (d->fd >= 0) {
1684 if (epoll_ctl(e->epoll_fd, EPOLL_CTL_DEL2, d->fd, NULL((void*)0)) < 0)
1685 log_debug_errno(errno, "Failed to remove inotify fd from epoll, ignoring: %m")({ int _level = ((7)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/libsystemd/sd-event/sd-event.c",
1685, __func__, "Failed to remove inotify fd from epoll, ignoring: %m"
) : -abs(_e); })
;
1686
1687 safe_close(d->fd);
1688 }
1689 free(d);
1690}
1691
1692static int event_make_inotify_data(
1693 sd_event *e,
1694 int64_t priority,
1695 struct inotify_data **ret) {
1696
1697 _cleanup_close___attribute__((cleanup(closep))) int fd = -1;
1698 struct inotify_data *d;
1699 struct epoll_event ev;
1700 int r;
1701
1702 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1702, __PRETTY_FUNCTION__); } while (0)
;
1703
1704 d = hashmap_get(e->inotify_data, &priority);
1705 if (d) {
1706 if (ret)
1707 *ret = d;
1708 return 0;
1709 }
1710
1711 fd = inotify_init1(IN_NONBLOCKIN_NONBLOCK|O_CLOEXEC02000000);
1712 if (fd < 0)
1713 return -errno(*__errno_location ());
1714
1715 fd = fd_move_above_stdio(fd);
1716
1717 r = hashmap_ensure_allocated(&e->inotify_data, &uint64_hash_ops)internal_hashmap_ensure_allocated(&e->inotify_data, &
uint64_hash_ops )
;
1718 if (r < 0)
1719 return r;
1720
1721 d = new(struct inotify_data, 1)((struct inotify_data*) malloc_multiply(sizeof(struct inotify_data
), (1)))
;
1722 if (!d)
1723 return -ENOMEM12;
1724
1725 *d = (struct inotify_data) {
1726 .wakeup = WAKEUP_INOTIFY_DATA,
1727 .fd = TAKE_FD(fd)({ int _fd_ = (fd); (fd) = -1; _fd_; }),
1728 .priority = priority,
1729 };
1730
1731 r = hashmap_put(e->inotify_data, &d->priority, d);
1732 if (r < 0) {
1733 d->fd = safe_close(d->fd);
1734 free(d);
1735 return r;
1736 }
1737
1738 ev = (struct epoll_event) {
1739 .events = EPOLLINEPOLLIN,
1740 .data.ptr = d,
1741 };
1742
1743 if (epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD1, d->fd, &ev) < 0) {
1744 r = -errno(*__errno_location ());
1745 d->fd = safe_close(d->fd); /* let's close this ourselves, as event_free_inotify_data() would otherwise
1746 * remove the fd from the epoll first, which we don't want as we couldn't
1747 * add it in the first place. */
1748 event_free_inotify_data(e, d);
1749 return r;
1750 }
1751
1752 if (ret)
1753 *ret = d;
1754
1755 return 1;
1756}
1757
1758static int inode_data_compare(const void *a, const void *b) {
1759 const struct inode_data *x = a, *y = b;
1760
1761 assert(x)do { if ((__builtin_expect(!!(!(x)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("x"), "../src/libsystemd/sd-event/sd-event.c"
, 1761, __PRETTY_FUNCTION__); } while (0)
;
1762 assert(y)do { if ((__builtin_expect(!!(!(y)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("y"), "../src/libsystemd/sd-event/sd-event.c"
, 1762, __PRETTY_FUNCTION__); } while (0)
;
1763
1764 if (x->dev < y->dev)
1765 return -1;
1766 if (x->dev > y->dev)
1767 return 1;
1768
1769 if (x->ino < y->ino)
1770 return -1;
1771 if (x->ino > y->ino)
1772 return 1;
1773
1774 return 0;
1775}
1776
1777static void inode_data_hash_func(const void *p, struct siphash *state) {
1778 const struct inode_data *d = p;
1779
1780 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/libsystemd/sd-event/sd-event.c"
, 1780, __PRETTY_FUNCTION__); } while (0)
;
1781
1782 siphash24_compress(&d->dev, sizeof(d->dev), state);
1783 siphash24_compress(&d->ino, sizeof(d->ino), state);
1784}
1785
1786const struct hash_ops inode_data_hash_ops = {
1787 .hash = inode_data_hash_func,
1788 .compare = inode_data_compare
1789};
1790
1791static void event_free_inode_data(
1792 sd_event *e,
1793 struct inode_data *d) {
1794
1795 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1795, __PRETTY_FUNCTION__); } while (0)
;
1796
1797 if (!d)
1798 return;
1799
1800 assert(!d->event_sources)do { if ((__builtin_expect(!!(!(!d->event_sources)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!d->event_sources"), "../src/libsystemd/sd-event/sd-event.c"
, 1800, __PRETTY_FUNCTION__); } while (0)
;
1801
1802 if (d->fd >= 0) {
1803 LIST_REMOVE(to_close, e->inode_data_to_close, d)do { typeof(*(e->inode_data_to_close)) **_head = &(e->
inode_data_to_close), *_item = (d); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd/sd-event/sd-event.c", 1803, __PRETTY_FUNCTION__
); } while (0); if (_item->to_close_next) _item->to_close_next
->to_close_prev = _item->to_close_prev; if (_item->to_close_prev
) _item->to_close_prev->to_close_next = _item->to_close_next
; else { do { if ((__builtin_expect(!!(!(*_head == _item)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*_head == _item"
), "../src/libsystemd/sd-event/sd-event.c", 1803, __PRETTY_FUNCTION__
); } while (0); *_head = _item->to_close_next; } _item->
to_close_next = _item->to_close_prev = ((void*)0); } while
(0)
;
1804 safe_close(d->fd);
1805 }
1806
1807 if (d->inotify_data) {
1808
1809 if (d->wd >= 0) {
1810 if (d->inotify_data->fd >= 0) {
1811 /* So here's a problem. At the time this runs the watch descriptor might already be
1812 * invalidated, because an IN_IGNORED event might be queued right the moment we enter
1813 * the syscall. Hence, whenever we get EINVAL, ignore it entirely, since it's a very
1814 * likely case to happen. */
1815
1816 if (inotify_rm_watch(d->inotify_data->fd, d->wd) < 0 && errno(*__errno_location ()) != EINVAL22)
1817 log_debug_errno(errno, "Failed to remove watch descriptor %i from inotify, ignoring: %m", d->wd)({ int _level = ((7)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/libsystemd/sd-event/sd-event.c",
1817, __func__, "Failed to remove watch descriptor %i from inotify, ignoring: %m"
, d->wd) : -abs(_e); })
;
1818 }
1819
1820 assert_se(hashmap_remove(d->inotify_data->wd, INT_TO_PTR(d->wd)) == d)do { if ((__builtin_expect(!!(!(hashmap_remove(d->inotify_data
->wd, ((void *) ((intptr_t) (d->wd)))) == d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("hashmap_remove(d->inotify_data->wd, INT_TO_PTR(d->wd)) == d"
), "../src/libsystemd/sd-event/sd-event.c", 1820, __PRETTY_FUNCTION__
); } while (0)
;
1821 }
1822
1823 assert_se(hashmap_remove(d->inotify_data->inodes, d) == d)do { if ((__builtin_expect(!!(!(hashmap_remove(d->inotify_data
->inodes, d) == d)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("hashmap_remove(d->inotify_data->inodes, d) == d"), "../src/libsystemd/sd-event/sd-event.c"
, 1823, __PRETTY_FUNCTION__); } while (0)
;
1824 }
1825
1826 free(d);
1827}
1828
1829static void event_gc_inode_data(
1830 sd_event *e,
1831 struct inode_data *d) {
1832
1833 struct inotify_data *inotify_data;
1834
1835 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1835, __PRETTY_FUNCTION__); } while (0)
;
1836
1837 if (!d)
1838 return;
1839
1840 if (d->event_sources)
1841 return;
1842
1843 inotify_data = d->inotify_data;
1844 event_free_inode_data(e, d);
1845
1846 if (inotify_data && hashmap_isempty(inotify_data->inodes))
1847 event_free_inotify_data(e, inotify_data);
1848}
1849
1850static int event_make_inode_data(
1851 sd_event *e,
1852 struct inotify_data *inotify_data,
1853 dev_t dev,
1854 ino_t ino,
1855 struct inode_data **ret) {
1856
1857 struct inode_data *d, key;
1858 int r;
1859
1860 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1860, __PRETTY_FUNCTION__); } while (0)
;
1861 assert(inotify_data)do { if ((__builtin_expect(!!(!(inotify_data)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("inotify_data"), "../src/libsystemd/sd-event/sd-event.c"
, 1861, __PRETTY_FUNCTION__); } while (0)
;
1862
1863 key = (struct inode_data) {
1864 .ino = ino,
1865 .dev = dev,
1866 };
1867
1868 d = hashmap_get(inotify_data->inodes, &key);
1869 if (d) {
1870 if (ret)
1871 *ret = d;
1872
1873 return 0;
1874 }
1875
1876 r = hashmap_ensure_allocated(&inotify_data->inodes, &inode_data_hash_ops)internal_hashmap_ensure_allocated(&inotify_data->inodes
, &inode_data_hash_ops )
;
1877 if (r < 0)
1878 return r;
1879
1880 d = new(struct inode_data, 1)((struct inode_data*) malloc_multiply(sizeof(struct inode_data
), (1)))
;
1881 if (!d)
1882 return -ENOMEM12;
1883
1884 *d = (struct inode_data) {
1885 .dev = dev,
1886 .ino = ino,
1887 .wd = -1,
1888 .fd = -1,
1889 .inotify_data = inotify_data,
1890 };
1891
1892 r = hashmap_put(inotify_data->inodes, d, d);
1893 if (r < 0) {
1894 free(d);
1895 return r;
1896 }
1897
1898 if (ret)
1899 *ret = d;
1900
1901 return 1;
1902}
1903
1904static uint32_t inode_data_determine_mask(struct inode_data *d) {
1905 bool_Bool excl_unlink = true1;
1906 uint32_t combined = 0;
1907 sd_event_source *s;
1908
1909 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 1909, __PRETTY_FUNCTION__); } while (0)
;
1910
1911 /* Combines the watch masks of all event sources watching this inode. We generally just OR them together, but
1912 * the IN_EXCL_UNLINK flag is ANDed instead.
1913 *
1914 * Note that we add all sources to the mask here, regardless whether enabled, disabled or oneshot. That's
1915 * because we cannot change the mask anymore after the event source was created once, since the kernel has no
1916 * API for that. Hence we need to subscribe to the maximum mask we ever might be interested in, and supress
1917 * events we don't care for client-side. */
1918
1919 LIST_FOREACH(inotify.by_inode_data, s, d->event_sources)for ((s) = (d->event_sources); (s); (s) = (s)->inotify.
by_inode_data_next)
{
1920
1921 if ((s->inotify.mask & IN_EXCL_UNLINK0x04000000) == 0)
1922 excl_unlink = false0;
1923
1924 combined |= s->inotify.mask;
1925 }
1926
1927 return (combined & ~(IN_ONESHOT0x80000000|IN_DONT_FOLLOW0x02000000|IN_ONLYDIR0x01000000|IN_EXCL_UNLINK0x04000000)) | (excl_unlink ? IN_EXCL_UNLINK0x04000000 : 0);
1928}
1929
1930static int inode_data_realize_watch(sd_event *e, struct inode_data *d) {
1931 uint32_t combined_mask;
1932 int wd, r;
1933
1934 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 1934, __PRETTY_FUNCTION__); } while (0)
;
1935 assert(d->fd >= 0)do { if ((__builtin_expect(!!(!(d->fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d->fd >= 0"), "../src/libsystemd/sd-event/sd-event.c"
, 1935, __PRETTY_FUNCTION__); } while (0)
;
1936
1937 combined_mask = inode_data_determine_mask(d);
1938
1939 if (d->wd >= 0 && combined_mask == d->combined_mask)
1940 return 0;
1941
1942 r = hashmap_ensure_allocated(&d->inotify_data->wd, NULL)internal_hashmap_ensure_allocated(&d->inotify_data->
wd, ((void*)0) )
;
1943 if (r < 0)
1944 return r;
1945
1946 wd = inotify_add_watch_fd(d->inotify_data->fd, d->fd, combined_mask);
1947 if (wd < 0)
1948 return -errno(*__errno_location ());
1949
1950 if (d->wd < 0) {
1951 r = hashmap_put(d->inotify_data->wd, INT_TO_PTR(wd)((void *) ((intptr_t) (wd))), d);
1952 if (r < 0) {
1953 (void) inotify_rm_watch(d->inotify_data->fd, wd);
1954 return r;
1955 }
1956
1957 d->wd = wd;
1958
1959 } else if (d->wd != wd) {
1960
1961 log_debug("Weird, the watch descriptor we already knew for this inode changed?")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-event/sd-event.c", 1961, __func__, "Weird, the watch descriptor we already knew for this inode changed?"
) : -abs(_e); })
;
1962 (void) inotify_rm_watch(d->fd, wd);
1963 return -EINVAL22;
1964 }
1965
1966 d->combined_mask = combined_mask;
1967 return 1;
1968}
1969
1970_public___attribute__ ((visibility("default"))) int sd_event_add_inotify(
1971 sd_event *e,
1972 sd_event_source **ret,
1973 const char *path,
1974 uint32_t mask,
1975 sd_event_inotify_handler_t callback,
1976 void *userdata) {
1977
1978 bool_Bool rm_inotify = false0, rm_inode = false0;
1979 struct inotify_data *inotify_data = NULL((void*)0);
1980 struct inode_data *inode_data = NULL((void*)0);
1981 _cleanup_close___attribute__((cleanup(closep))) int fd = -1;
1982 sd_event_source *s;
1983 struct stat st;
1984 int r;
1985
1986 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 1986, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1987 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1987, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
1988 assert_return(path, -EINVAL)do { if (!(((__builtin_expect(!!(path),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/libsystemd/sd-event/sd-event.c"
, 1988, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1989 assert_return(callback, -EINVAL)do { if (!(((__builtin_expect(!!(callback),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("callback"), "../src/libsystemd/sd-event/sd-event.c"
, 1989, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1990 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 1990, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
1991 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 1991, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
1992
1993 /* Refuse IN_MASK_ADD since we coalesce watches on the same inode, and hence really don't want to merge
1994 * masks. Or in other words, this whole code exists only to manage IN_MASK_ADD type operations for you, hence
1995 * the user can't use them for us. */
1996 if (mask & IN_MASK_ADD0x20000000)
1997 return -EINVAL22;
1998
1999 fd = open(path, O_PATH010000000|O_CLOEXEC02000000|
2000 (mask & IN_ONLYDIR0x01000000 ? O_DIRECTORY0200000 : 0)|
2001 (mask & IN_DONT_FOLLOW0x02000000 ? O_NOFOLLOW0400000 : 0));
2002 if (fd < 0)
2003 return -errno(*__errno_location ());
2004
2005 if (fstat(fd, &st) < 0)
2006 return -errno(*__errno_location ());
2007
2008 s = source_new(e, !ret, SOURCE_INOTIFY);
2009 if (!s)
2010 return -ENOMEM12;
2011
2012 s->enabled = mask & IN_ONESHOT0x80000000 ? SD_EVENT_ONESHOT : SD_EVENT_ON;
2013 s->inotify.mask = mask;
2014 s->inotify.callback = callback;
2015 s->userdata = userdata;
2016
2017 /* Allocate an inotify object for this priority, and an inode object within it */
2018 r = event_make_inotify_data(e, SD_EVENT_PRIORITY_NORMAL, &inotify_data);
2019 if (r < 0)
2020 goto fail;
2021 rm_inotify = r > 0;
2022
2023 r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data);
2024 if (r < 0)
2025 goto fail;
2026 rm_inode = r > 0;
Value stored to 'rm_inode' is never read
2027
2028 /* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of
2029 * the event source, until then, for which we need the original inode. */
2030 if (inode_data->fd < 0) {
2031 inode_data->fd = TAKE_FD(fd)({ int _fd_ = (fd); (fd) = -1; _fd_; });
2032 LIST_PREPEND(to_close, e->inode_data_to_close, inode_data)do { typeof(*(e->inode_data_to_close)) **_head = &(e->
inode_data_to_close), *_item = (inode_data); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd/sd-event/sd-event.c", 2032, __PRETTY_FUNCTION__
); } while (0); if ((_item->to_close_next = *_head)) _item
->to_close_next->to_close_prev = _item; _item->to_close_prev
= ((void*)0); *_head = _item; } while (0)
;
2033 }
2034
2035 /* Link our event source to the inode data object */
2036 LIST_PREPEND(inotify.by_inode_data, inode_data->event_sources, s)do { typeof(*(inode_data->event_sources)) **_head = &(
inode_data->event_sources), *_item = (s); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd/sd-event/sd-event.c", 2036, __PRETTY_FUNCTION__
); } while (0); if ((_item->inotify.by_inode_data_next = *
_head)) _item->inotify.by_inode_data_next->inotify.by_inode_data_prev
= _item; _item->inotify.by_inode_data_prev = ((void*)0); *
_head = _item; } while (0)
;
2037 s->inotify.inode_data = inode_data;
2038
2039 rm_inode = rm_inotify = false0;
2040
2041 /* Actually realize the watch now */
2042 r = inode_data_realize_watch(e, inode_data);
2043 if (r < 0)
2044 goto fail;
2045
2046 (void) sd_event_source_set_description(s, path);
2047
2048 if (ret)
2049 *ret = s;
2050
2051 return 0;
2052
2053fail:
2054 source_free(s);
2055
2056 if (rm_inode)
2057 event_free_inode_data(e, inode_data);
2058
2059 if (rm_inotify)
2060 event_free_inotify_data(e, inotify_data);
2061
2062 return r;
2063}
2064
2065_public___attribute__ ((visibility("default"))) sd_event_source* sd_event_source_ref(sd_event_source *s) {
2066
2067 if (!s)
2068 return NULL((void*)0);
2069
2070 assert(s->n_ref >= 1)do { if ((__builtin_expect(!!(!(s->n_ref >= 1)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s->n_ref >= 1"), "../src/libsystemd/sd-event/sd-event.c"
, 2070, __PRETTY_FUNCTION__); } while (0)
;
2071 s->n_ref++;
2072
2073 return s;
2074}
2075
2076_public___attribute__ ((visibility("default"))) sd_event_source* sd_event_source_unref(sd_event_source *s) {
2077
2078 if (!s)
2079 return NULL((void*)0);
2080
2081 assert(s->n_ref >= 1)do { if ((__builtin_expect(!!(!(s->n_ref >= 1)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s->n_ref >= 1"), "../src/libsystemd/sd-event/sd-event.c"
, 2081, __PRETTY_FUNCTION__); } while (0)
;
2082 s->n_ref--;
2083
2084 if (s->n_ref <= 0) {
2085 /* Here's a special hack: when we are called from a
2086 * dispatch handler we won't free the event source
2087 * immediately, but we will detach the fd from the
2088 * epoll. This way it is safe for the caller to unref
2089 * the event source and immediately close the fd, but
2090 * we still retain a valid event source object after
2091 * the callback. */
2092
2093 if (s->dispatching) {
2094 if (s->type == SOURCE_IO)
2095 source_io_unregister(s);
2096
2097 source_disconnect(s);
2098 } else
2099 source_free(s);
2100 }
2101
2102 return NULL((void*)0);
2103}
2104
2105_public___attribute__ ((visibility("default"))) int sd_event_source_set_description(sd_event_source *s, const char *description) {
2106 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2106, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2107 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2107, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2108
2109 return free_and_strdup(&s->description, description);
2110}
2111
2112_public___attribute__ ((visibility("default"))) int sd_event_source_get_description(sd_event_source *s, const char **description) {
2113 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2113, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2114 assert_return(description, -EINVAL)do { if (!(((__builtin_expect(!!(description),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("description"), "../src/libsystemd/sd-event/sd-event.c"
, 2114, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2115 assert_return(s->description, -ENXIO)do { if (!(((__builtin_expect(!!(s->description),1))) ? (1
) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("s->description"
), "../src/libsystemd/sd-event/sd-event.c", 2115, __PRETTY_FUNCTION__
), 0))) return (-6); } while (0)
;
2116 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2116, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2117
2118 *description = s->description;
2119 return 0;
2120}
2121
2122_public___attribute__ ((visibility("default"))) sd_event *sd_event_source_get_event(sd_event_source *s) {
2123 assert_return(s, NULL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2123, __PRETTY_FUNCTION__), 0))) return (((void*)0)); } while
(0)
;
2124
2125 return s->event;
2126}
2127
2128_public___attribute__ ((visibility("default"))) int sd_event_source_get_pending(sd_event_source *s) {
2129 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2129, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2130 assert_return(s->type != SOURCE_EXIT, -EDOM)do { if (!(((__builtin_expect(!!(s->type != SOURCE_EXIT),1
))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("s->type != SOURCE_EXIT"), "../src/libsystemd/sd-event/sd-event.c"
, 2130, __PRETTY_FUNCTION__), 0))) return (-33); } while (0)
;
2131 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(s->event->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("s->event->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 2131, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
2132 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2132, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2133
2134 return s->pending;
2135}
2136
2137_public___attribute__ ((visibility("default"))) int sd_event_source_get_io_fd(sd_event_source *s) {
2138 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2138, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2139 assert_return(s->type == SOURCE_IO, -EDOM)do { if (!(((__builtin_expect(!!(s->type == SOURCE_IO),1))
) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, (
"s->type == SOURCE_IO"), "../src/libsystemd/sd-event/sd-event.c"
, 2139, __PRETTY_FUNCTION__), 0))) return (-33); } while (0)
;
2140 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2140, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2141
2142 return s->io.fd;
2143}
2144
2145_public___attribute__ ((visibility("default"))) int sd_event_source_set_io_fd(sd_event_source *s, int fd) {
2146 int r;
2147
2148 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2148, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2149 assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/libsystemd/sd-event/sd-event.c"
, 2149, __PRETTY_FUNCTION__), 0))) return (-9); } while (0)
;
2150 assert_return(s->type == SOURCE_IO, -EDOM)do { if (!(((__builtin_expect(!!(s->type == SOURCE_IO),1))
) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, (
"s->type == SOURCE_IO"), "../src/libsystemd/sd-event/sd-event.c"
, 2150, __PRETTY_FUNCTION__), 0))) return (-33); } while (0)
;
2151 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2151, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2152
2153 if (s->io.fd == fd)
2154 return 0;
2155
2156 if (event_source_is_offline(s)) {
2157 s->io.fd = fd;
2158 s->io.registered = false0;
2159 } else {
2160 int saved_fd;
2161
2162 saved_fd = s->io.fd;
2163 assert(s->io.registered)do { if ((__builtin_expect(!!(!(s->io.registered)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s->io.registered"), "../src/libsystemd/sd-event/sd-event.c"
, 2163, __PRETTY_FUNCTION__); } while (0)
;
2164
2165 s->io.fd = fd;
2166 s->io.registered = false0;
2167
2168 r = source_io_register(s, s->enabled, s->io.events);
2169 if (r < 0) {
2170 s->io.fd = saved_fd;
2171 s->io.registered = true1;
2172 return r;
2173 }
2174
2175 epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL2, saved_fd, NULL((void*)0));
2176 }
2177
2178 return 0;
2179}
2180
2181_public___attribute__ ((visibility("default"))) int sd_event_source_get_io_fd_own(sd_event_source *s) {
2182 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2182, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2183 assert_return(s->type == SOURCE_IO, -EDOM)do { if (!(((__builtin_expect(!!(s->type == SOURCE_IO),1))
) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, (
"s->type == SOURCE_IO"), "../src/libsystemd/sd-event/sd-event.c"
, 2183, __PRETTY_FUNCTION__), 0))) return (-33); } while (0)
;
2184
2185 return s->io.owned;
2186}
2187
2188_public___attribute__ ((visibility("default"))) int sd_event_source_set_io_fd_own(sd_event_source *s, int own) {
2189 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2189, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2190 assert_return(s->type == SOURCE_IO, -EDOM)do { if (!(((__builtin_expect(!!(s->type == SOURCE_IO),1))
) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, (
"s->type == SOURCE_IO"), "../src/libsystemd/sd-event/sd-event.c"
, 2190, __PRETTY_FUNCTION__), 0))) return (-33); } while (0)
;
2191
2192 s->io.owned = own;
2193 return 0;
2194}
2195
2196_public___attribute__ ((visibility("default"))) int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) {
2197 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2197, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2198 assert_return(events, -EINVAL)do { if (!(((__builtin_expect(!!(events),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("events"), "../src/libsystemd/sd-event/sd-event.c"
, 2198, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2199 assert_return(s->type == SOURCE_IO, -EDOM)do { if (!(((__builtin_expect(!!(s->type == SOURCE_IO),1))
) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, (
"s->type == SOURCE_IO"), "../src/libsystemd/sd-event/sd-event.c"
, 2199, __PRETTY_FUNCTION__), 0))) return (-33); } while (0)
;
2200 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2200, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2201
2202 *events = s->io.events;
2203 return 0;
2204}
2205
2206_public___attribute__ ((visibility("default"))) int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) {
2207 int r;
2208
2209 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2209, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2210 assert_return(s->type == SOURCE_IO, -EDOM)do { if (!(((__builtin_expect(!!(s->type == SOURCE_IO),1))
) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, (
"s->type == SOURCE_IO"), "../src/libsystemd/sd-event/sd-event.c"
, 2210, __PRETTY_FUNCTION__), 0))) return (-33); } while (0)
;
2211 assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL)do { if (!(((__builtin_expect(!!(!(events & ~(EPOLLIN|EPOLLOUT
|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET))),1))) ? (1) :
(log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET))"
), "../src/libsystemd/sd-event/sd-event.c", 2211, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
2212 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(s->event->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("s->event->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 2212, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
2213 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2213, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2214
2215 /* edge-triggered updates are never skipped, so we can reset edges */
2216 if (s->io.events == events && !(events & EPOLLETEPOLLET))
2217 return 0;
2218
2219 r = source_set_pending(s, false0);
2220 if (r < 0)
2221 return r;
2222
2223 if (event_source_is_online(s)) {
2224 r = source_io_register(s, s->enabled, events);
2225 if (r < 0)
2226 return r;
2227 }
2228
2229 s->io.events = events;
2230
2231 return 0;
2232}
2233
2234_public___attribute__ ((visibility("default"))) int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents) {
2235 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2235, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2236 assert_return(revents, -EINVAL)do { if (!(((__builtin_expect(!!(revents),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("revents"), "../src/libsystemd/sd-event/sd-event.c"
, 2236, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2237 assert_return(s->type == SOURCE_IO, -EDOM)do { if (!(((__builtin_expect(!!(s->type == SOURCE_IO),1))
) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, (
"s->type == SOURCE_IO"), "../src/libsystemd/sd-event/sd-event.c"
, 2237, __PRETTY_FUNCTION__), 0))) return (-33); } while (0)
;
2238 assert_return(s->pending, -ENODATA)do { if (!(((__builtin_expect(!!(s->pending),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("s->pending"
), "../src/libsystemd/sd-event/sd-event.c", 2238, __PRETTY_FUNCTION__
), 0))) return (-61); } while (0)
;
2239 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2239, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2240
2241 *revents = s->io.revents;
2242 return 0;
2243}
2244
2245_public___attribute__ ((visibility("default"))) int sd_event_source_get_signal(sd_event_source *s) {
2246 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2246, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2247 assert_return(s->type == SOURCE_SIGNAL, -EDOM)do { if (!(((__builtin_expect(!!(s->type == SOURCE_SIGNAL)
,1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("s->type == SOURCE_SIGNAL"), "../src/libsystemd/sd-event/sd-event.c"
, 2247, __PRETTY_FUNCTION__), 0))) return (-33); } while (0)
;
2248 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2248, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2249
2250 return s->signal.sig;
2251}
2252
2253_public___attribute__ ((visibility("default"))) int sd_event_source_get_priority(sd_event_source *s, int64_t *priority) {
2254 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2254, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2255 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2255, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2256
2257 *priority = s->priority;
2258 return 0;
2259}
2260
2261_public___attribute__ ((visibility("default"))) int sd_event_source_set_priority(sd_event_source *s, int64_t priority) {
2262 bool_Bool rm_inotify = false0, rm_inode = false0;
2263 struct inotify_data *new_inotify_data = NULL((void*)0);
2264 struct inode_data *new_inode_data = NULL((void*)0);
2265 int r;
2266
2267 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2267, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2268 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(s->event->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("s->event->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 2268, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
2269 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2269, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2270
2271 if (s->priority == priority)
2272 return 0;
2273
2274 if (s->type == SOURCE_INOTIFY) {
2275 struct inode_data *old_inode_data;
2276
2277 assert(s->inotify.inode_data)do { if ((__builtin_expect(!!(!(s->inotify.inode_data)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->inotify.inode_data"
), "../src/libsystemd/sd-event/sd-event.c", 2277, __PRETTY_FUNCTION__
); } while (0)
;
2278 old_inode_data = s->inotify.inode_data;
2279
2280 /* We need the original fd to change the priority. If we don't have it we can't change the priority,
2281 * anymore. Note that we close any fds when entering the next event loop iteration, i.e. for inotify
2282 * events we allow priority changes only until the first following iteration. */
2283 if (old_inode_data->fd < 0)
2284 return -EOPNOTSUPP95;
2285
2286 r = event_make_inotify_data(s->event, priority, &new_inotify_data);
2287 if (r < 0)
2288 return r;
2289 rm_inotify = r > 0;
2290
2291 r = event_make_inode_data(s->event, new_inotify_data, old_inode_data->dev, old_inode_data->ino, &new_inode_data);
2292 if (r < 0)
2293 goto fail;
2294 rm_inode = r > 0;
2295
2296 if (new_inode_data->fd < 0) {
2297 /* Duplicate the fd for the new inode object if we don't have any yet */
2298 new_inode_data->fd = fcntl(old_inode_data->fd, F_DUPFD_CLOEXEC1030, 3);
2299 if (new_inode_data->fd < 0) {
2300 r = -errno(*__errno_location ());
2301 goto fail;
2302 }
2303
2304 LIST_PREPEND(to_close, s->event->inode_data_to_close, new_inode_data)do { typeof(*(s->event->inode_data_to_close)) **_head =
&(s->event->inode_data_to_close), *_item = (new_inode_data
); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_item"), "../src/libsystemd/sd-event/sd-event.c"
, 2304, __PRETTY_FUNCTION__); } while (0); if ((_item->to_close_next
= *_head)) _item->to_close_next->to_close_prev = _item
; _item->to_close_prev = ((void*)0); *_head = _item; } while
(0)
;
2305 }
2306
2307 /* Move the event source to the new inode data structure */
2308 LIST_REMOVE(inotify.by_inode_data, old_inode_data->event_sources, s)do { typeof(*(old_inode_data->event_sources)) **_head = &
(old_inode_data->event_sources), *_item = (s); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd/sd-event/sd-event.c", 2308, __PRETTY_FUNCTION__
); } while (0); if (_item->inotify.by_inode_data_next) _item
->inotify.by_inode_data_next->inotify.by_inode_data_prev
= _item->inotify.by_inode_data_prev; if (_item->inotify
.by_inode_data_prev) _item->inotify.by_inode_data_prev->
inotify.by_inode_data_next = _item->inotify.by_inode_data_next
; else { do { if ((__builtin_expect(!!(!(*_head == _item)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*_head == _item"
), "../src/libsystemd/sd-event/sd-event.c", 2308, __PRETTY_FUNCTION__
); } while (0); *_head = _item->inotify.by_inode_data_next
; } _item->inotify.by_inode_data_next = _item->inotify.
by_inode_data_prev = ((void*)0); } while (0)
;
2309 LIST_PREPEND(inotify.by_inode_data, new_inode_data->event_sources, s)do { typeof(*(new_inode_data->event_sources)) **_head = &
(new_inode_data->event_sources), *_item = (s); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd/sd-event/sd-event.c", 2309, __PRETTY_FUNCTION__
); } while (0); if ((_item->inotify.by_inode_data_next = *
_head)) _item->inotify.by_inode_data_next->inotify.by_inode_data_prev
= _item; _item->inotify.by_inode_data_prev = ((void*)0); *
_head = _item; } while (0)
;
2310 s->inotify.inode_data = new_inode_data;
2311
2312 /* Now create the new watch */
2313 r = inode_data_realize_watch(s->event, new_inode_data);
2314 if (r < 0) {
2315 /* Move it back */
2316 LIST_REMOVE(inotify.by_inode_data, new_inode_data->event_sources, s)do { typeof(*(new_inode_data->event_sources)) **_head = &
(new_inode_data->event_sources), *_item = (s); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd/sd-event/sd-event.c", 2316, __PRETTY_FUNCTION__
); } while (0); if (_item->inotify.by_inode_data_next) _item
->inotify.by_inode_data_next->inotify.by_inode_data_prev
= _item->inotify.by_inode_data_prev; if (_item->inotify
.by_inode_data_prev) _item->inotify.by_inode_data_prev->
inotify.by_inode_data_next = _item->inotify.by_inode_data_next
; else { do { if ((__builtin_expect(!!(!(*_head == _item)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*_head == _item"
), "../src/libsystemd/sd-event/sd-event.c", 2316, __PRETTY_FUNCTION__
); } while (0); *_head = _item->inotify.by_inode_data_next
; } _item->inotify.by_inode_data_next = _item->inotify.
by_inode_data_prev = ((void*)0); } while (0)
;
2317 LIST_PREPEND(inotify.by_inode_data, old_inode_data->event_sources, s)do { typeof(*(old_inode_data->event_sources)) **_head = &
(old_inode_data->event_sources), *_item = (s); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd/sd-event/sd-event.c", 2317, __PRETTY_FUNCTION__
); } while (0); if ((_item->inotify.by_inode_data_next = *
_head)) _item->inotify.by_inode_data_next->inotify.by_inode_data_prev
= _item; _item->inotify.by_inode_data_prev = ((void*)0); *
_head = _item; } while (0)
;
2318 s->inotify.inode_data = old_inode_data;
2319 goto fail;
2320 }
2321
2322 s->priority = priority;
2323
2324 event_gc_inode_data(s->event, old_inode_data);
2325
2326 } else if (s->type == SOURCE_SIGNAL && event_source_is_online(s)) {
2327 struct signal_data *old, *d;
2328
2329 /* Move us from the signalfd belonging to the old
2330 * priority to the signalfd of the new priority */
2331
2332 assert_se(old = hashmap_get(s->event->signal_data, &s->priority))do { if ((__builtin_expect(!!(!(old = hashmap_get(s->event
->signal_data, &s->priority))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("old = hashmap_get(s->event->signal_data, &s->priority)"
), "../src/libsystemd/sd-event/sd-event.c", 2332, __PRETTY_FUNCTION__
); } while (0)
;
2333
2334 s->priority = priority;
2335
2336 r = event_make_signal_data(s->event, s->signal.sig, &d);
2337 if (r < 0) {
2338 s->priority = old->priority;
2339 return r;
2340 }
2341
2342 event_unmask_signal_data(s->event, old, s->signal.sig);
2343 } else
2344 s->priority = priority;
2345
2346 event_source_pp_prioq_reshuffle(s);
2347
2348 if (s->type == SOURCE_EXIT)
2349 prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
2350
2351 return 0;
2352
2353fail:
2354 if (rm_inode)
2355 event_free_inode_data(s->event, new_inode_data);
2356
2357 if (rm_inotify)
2358 event_free_inotify_data(s->event, new_inotify_data);
2359
2360 return r;
2361}
2362
2363_public___attribute__ ((visibility("default"))) int sd_event_source_get_enabled(sd_event_source *s, int *ret) {
2364 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2364, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2365 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2365, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2366
2367 if (ret)
2368 *ret = s->enabled;
2369
2370 return s->enabled != SD_EVENT_OFF;
2371}
2372
2373static int event_source_offline(
2374 sd_event_source *s,
2375 int enabled,
2376 bool_Bool ratelimited) {
2377
2378 bool_Bool was_offline;
2379 int r;
2380
2381 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2381, __PRETTY_FUNCTION__); } while (0)
;
2382 assert(enabled == SD_EVENT_OFF || ratelimited)do { if ((__builtin_expect(!!(!(enabled == SD_EVENT_OFF || ratelimited
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("enabled == SD_EVENT_OFF || ratelimited"
), "../src/libsystemd/sd-event/sd-event.c", 2382, __PRETTY_FUNCTION__
); } while (0)
;
2383
2384 /* Unset the pending flag when this event source is disabled */
2385 if (s->enabled != SD_EVENT_OFF &&
2386 enabled == SD_EVENT_OFF &&
2387 !IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_DEFER, SOURCE_EXIT})/sizeof(int)]
; switch(s->type) { case SOURCE_DEFER: case SOURCE_EXIT: _found
= 1; break; default: break; } _found; })
) {
2388 r = source_set_pending(s, false0);
2389 if (r < 0)
2390 return r;
2391 }
2392
2393 was_offline = event_source_is_offline(s);
2394 s->enabled = enabled;
2395 s->ratelimited = ratelimited;
2396
2397 switch (s->type) {
2398
2399 case SOURCE_IO:
2400 source_io_unregister(s);
2401 break;
2402
2403 case SOURCE_TIME_REALTIME:
2404 case SOURCE_TIME_BOOTTIME:
2405 case SOURCE_TIME_MONOTONIC:
2406 case SOURCE_TIME_REALTIME_ALARM:
2407 case SOURCE_TIME_BOOTTIME_ALARM:
2408 event_source_time_prioq_reshuffle(s);
2409 break;
2410
2411 case SOURCE_SIGNAL:
2412 event_gc_signal_data(s->event, &s->priority, s->signal.sig);
2413 break;
2414
2415 case SOURCE_CHILD:
2416 if (!was_offline) {
2417 assert(s->event->n_online_child_sources > 0)do { if ((__builtin_expect(!!(!(s->event->n_online_child_sources
> 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->event->n_online_child_sources > 0"
), "../src/libsystemd/sd-event/sd-event.c", 2417, __PRETTY_FUNCTION__
); } while (0)
;
2418 s->event->n_online_child_sources--;
2419 }
2420
2421 event_gc_signal_data(s->event, &s->priority, SIGCHLD17);
2422 break;
2423
2424 case SOURCE_EXIT:
2425 prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
2426 break;
2427
2428 case SOURCE_DEFER:
2429 case SOURCE_POST:
2430 case SOURCE_INOTIFY:
2431 break;
2432
2433 default:
2434 assert_not_reached("Wut? I shouldn't exist.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Wut? I shouldn't exist."), "../src/libsystemd/sd-event/sd-event.c"
, 2434, __PRETTY_FUNCTION__); } while (0)
;
2435 }
2436
2437 return 1;
2438}
2439
2440static int event_source_online(
2441 sd_event_source *s,
2442 int enabled,
2443 bool_Bool ratelimited) {
2444
2445 bool_Bool was_online;
2446 int r;
2447
2448 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2448, __PRETTY_FUNCTION__); } while (0)
;
2449 assert(enabled != SD_EVENT_OFF || !ratelimited)do { if ((__builtin_expect(!!(!(enabled != SD_EVENT_OFF || !ratelimited
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("enabled != SD_EVENT_OFF || !ratelimited"
), "../src/libsystemd/sd-event/sd-event.c", 2449, __PRETTY_FUNCTION__
); } while (0)
;
2450
2451 /* Unset the pending flag when this event source is enabled */
2452 if (s->enabled == SD_EVENT_OFF &&
2453 enabled != SD_EVENT_OFF &&
2454 !IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_DEFER, SOURCE_EXIT})/sizeof(int)]
; switch(s->type) { case SOURCE_DEFER: case SOURCE_EXIT: _found
= 1; break; default: break; } _found; })
) {
2455 r = source_set_pending(s, false0);
2456 if (r < 0)
2457 return r;
2458 }
2459
2460 /* Are we really ready for onlining? */
2461 if (enabled == SD_EVENT_OFF || ratelimited) {
2462 /* Nope, we are not ready for onlining, then just update the precise state and exit */
2463 s->enabled = enabled;
2464 s->ratelimited = ratelimited;
2465 return 0;
2466 }
2467
2468 was_online = event_source_is_online(s);
2469
2470 switch (s->type) {
2471 case SOURCE_IO:
2472 r = source_io_register(s, enabled, s->io.events);
2473 if (r < 0)
2474 return r;
2475 break;
2476
2477 case SOURCE_SIGNAL:
2478 r = event_make_signal_data(s->event, s->signal.sig, NULL((void*)0));
2479 if (r < 0) {
2480 event_gc_signal_data(s->event, &s->priority, s->signal.sig);
2481 return r;
2482 }
2483
2484 break;
2485
2486 case SOURCE_CHILD:
2487 r = event_make_signal_data(s->event, SIGCHLD17, NULL((void*)0));
2488 if (r < 0) {
2489 s->enabled = SD_EVENT_OFF;
2490 s->event->n_online_child_sources--;
2491 event_gc_signal_data(s->event, &s->priority, SIGCHLD17);
2492 return r;
2493 }
2494
2495 if (!was_online)
2496 s->event->n_online_child_sources++;
2497 break;
2498
2499 case SOURCE_TIME_REALTIME:
2500 case SOURCE_TIME_BOOTTIME:
2501 case SOURCE_TIME_MONOTONIC:
2502 case SOURCE_TIME_REALTIME_ALARM:
2503 case SOURCE_TIME_BOOTTIME_ALARM:
2504 case SOURCE_EXIT:
2505 case SOURCE_DEFER:
2506 case SOURCE_POST:
2507 case SOURCE_INOTIFY:
2508 break;
2509
2510 default:
2511 assert_not_reached("Wut? I shouldn't exist.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Wut? I shouldn't exist."), "../src/libsystemd/sd-event/sd-event.c"
, 2511, __PRETTY_FUNCTION__); } while (0)
;
2512 }
2513
2514 s->enabled = enabled;
2515 s->ratelimited = ratelimited;
2516
2517 /* Non-failing operations below */
2518 switch (s->type) {
2519 case SOURCE_TIME_REALTIME:
2520 case SOURCE_TIME_BOOTTIME:
2521 case SOURCE_TIME_MONOTONIC:
2522 case SOURCE_TIME_REALTIME_ALARM:
2523 case SOURCE_TIME_BOOTTIME_ALARM:
2524 event_source_time_prioq_reshuffle(s);
2525 break;
2526
2527 case SOURCE_EXIT:
2528 prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
2529 break;
2530
2531 default:
2532 break;
2533 }
2534
2535 return 1;
2536}
2537
2538_public___attribute__ ((visibility("default"))) int sd_event_source_set_enabled(sd_event_source *s, int m) {
2539 int r;
2540
2541 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2541, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2542 assert_return(IN_SET(m, SD_EVENT_OFF, SD_EVENT_ON, SD_EVENT_ONESHOT), -EINVAL)do { if (!(((__builtin_expect(!!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){SD_EVENT_OFF, SD_EVENT_ON, SD_EVENT_ONESHOT
})/sizeof(int)]; switch(m) { case SD_EVENT_OFF: case SD_EVENT_ON
: case SD_EVENT_ONESHOT: _found = 1; break; default: break; }
_found; })),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("IN_SET(m, SD_EVENT_OFF, SD_EVENT_ON, SD_EVENT_ONESHOT)"),
"../src/libsystemd/sd-event/sd-event.c", 2542, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
2543 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2543, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2544
2545 /* If we are dead anyway, we are fine with turning off sources, but everything else needs to fail. */
2546 if (s->event->state == SD_EVENT_FINISHED)
2547 return m == SD_EVENT_OFF ? 0 : -ESTALE116;
2548
2549 if (s->enabled == m) /* No change? */
2550 return 0;
2551
2552 if (m == SD_EVENT_OFF)
2553 r = event_source_offline(s, m, s->ratelimited);
2554 else {
2555 if (s->enabled != SD_EVENT_OFF) {
2556 /* Switching from "on" to "oneshot" or back? If that's the case, we can take a shortcut, the
2557 * event source is already enabled after all. */
2558 s->enabled = m;
2559 return 0;
2560 }
2561
2562 r = event_source_online(s, m, s->ratelimited);
2563 }
2564 if (r < 0)
2565 return r;
2566
2567 event_source_pp_prioq_reshuffle(s);
2568 return 0;
2569}
2570
2571_public___attribute__ ((visibility("default"))) int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
2572 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2572, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2573 assert_return(usec, -EINVAL)do { if (!(((__builtin_expect(!!(usec),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("usec"), "../src/libsystemd/sd-event/sd-event.c"
, 2573, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2574 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM)do { if (!(((__builtin_expect(!!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME,
SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; })),1))) ? (1) :
(log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("EVENT_SOURCE_IS_TIME(s->type)"
), "../src/libsystemd/sd-event/sd-event.c", 2574, __PRETTY_FUNCTION__
), 0))) return (-33); } while (0)
;
2575 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2575, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2576
2577 *usec = s->time.next;
2578 return 0;
2579}
2580
2581_public___attribute__ ((visibility("default"))) int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
2582 int r;
2583
2584 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2584, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2585 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM)do { if (!(((__builtin_expect(!!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME,
SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; })),1))) ? (1) :
(log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("EVENT_SOURCE_IS_TIME(s->type)"
), "../src/libsystemd/sd-event/sd-event.c", 2585, __PRETTY_FUNCTION__
), 0))) return (-33); } while (0)
;
2586 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(s->event->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("s->event->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 2586, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
2587 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2587, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2588
2589 r = source_set_pending(s, false0);
2590 if (r < 0)
2591 return r;
2592
2593 s->time.next = usec;
2594
2595 event_source_time_prioq_reshuffle(s);
2596 return 0;
2597}
2598
2599_public___attribute__ ((visibility("default"))) int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) {
2600 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2600, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2601 assert_return(usec, -EINVAL)do { if (!(((__builtin_expect(!!(usec),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("usec"), "../src/libsystemd/sd-event/sd-event.c"
, 2601, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2602 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM)do { if (!(((__builtin_expect(!!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME,
SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; })),1))) ? (1) :
(log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("EVENT_SOURCE_IS_TIME(s->type)"
), "../src/libsystemd/sd-event/sd-event.c", 2602, __PRETTY_FUNCTION__
), 0))) return (-33); } while (0)
;
2603 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2603, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2604
2605 *usec = s->time.accuracy;
2606 return 0;
2607}
2608
2609_public___attribute__ ((visibility("default"))) int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) {
2610 int r;
2611
2612 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2612, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2613 assert_return(usec != (uint64_t) -1, -EINVAL)do { if (!(((__builtin_expect(!!(usec != (uint64_t) -1),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("usec != (uint64_t) -1"
), "../src/libsystemd/sd-event/sd-event.c", 2613, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
2614 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM)do { if (!(((__builtin_expect(!!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME,
SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; })),1))) ? (1) :
(log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("EVENT_SOURCE_IS_TIME(s->type)"
), "../src/libsystemd/sd-event/sd-event.c", 2614, __PRETTY_FUNCTION__
), 0))) return (-33); } while (0)
;
2615 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(s->event->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("s->event->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 2615, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
2616 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2616, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2617
2618 r = source_set_pending(s, false0);
2619 if (r < 0)
2620 return r;
2621
2622 if (usec == 0)
2623 usec = DEFAULT_ACCURACY_USEC(250 * ((usec_t) 1000ULL));
2624
2625 s->time.accuracy = usec;
2626
2627 event_source_time_prioq_reshuffle(s);
2628 return 0;
2629}
2630
2631_public___attribute__ ((visibility("default"))) int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock) {
2632 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2632, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2633 assert_return(clock, -EINVAL)do { if (!(((__builtin_expect(!!(clock),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("clock"), "../src/libsystemd/sd-event/sd-event.c"
, 2633, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2634 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM)do { if (!(((__builtin_expect(!!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME,
SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; })),1))) ? (1) :
(log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("EVENT_SOURCE_IS_TIME(s->type)"
), "../src/libsystemd/sd-event/sd-event.c", 2634, __PRETTY_FUNCTION__
), 0))) return (-33); } while (0)
;
2635 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2635, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2636
2637 *clock = event_source_type_to_clock(s->type);
2638 return 0;
2639}
2640
2641_public___attribute__ ((visibility("default"))) int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) {
2642 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2642, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2643 assert_return(pid, -EINVAL)do { if (!(((__builtin_expect(!!(pid),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("pid"), "../src/libsystemd/sd-event/sd-event.c"
, 2643, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2644 assert_return(s->type == SOURCE_CHILD, -EDOM)do { if (!(((__builtin_expect(!!(s->type == SOURCE_CHILD),
1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("s->type == SOURCE_CHILD"), "../src/libsystemd/sd-event/sd-event.c"
, 2644, __PRETTY_FUNCTION__), 0))) return (-33); } while (0)
;
2645 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2645, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2646
2647 *pid = s->child.pid;
2648 return 0;
2649}
2650
2651_public___attribute__ ((visibility("default"))) int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *mask) {
2652 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2652, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2653 assert_return(mask, -EINVAL)do { if (!(((__builtin_expect(!!(mask),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("mask"), "../src/libsystemd/sd-event/sd-event.c"
, 2653, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2654 assert_return(s->type == SOURCE_INOTIFY, -EDOM)do { if (!(((__builtin_expect(!!(s->type == SOURCE_INOTIFY
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("s->type == SOURCE_INOTIFY"), "../src/libsystemd/sd-event/sd-event.c"
, 2654, __PRETTY_FUNCTION__), 0))) return (-33); } while (0)
;
2655 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2655, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2656
2657 *mask = s->inotify.mask;
2658 return 0;
2659}
2660
2661_public___attribute__ ((visibility("default"))) int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback) {
2662 int r;
2663
2664 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2664, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
2665 assert_return(s->type != SOURCE_EXIT, -EDOM)do { if (!(((__builtin_expect(!!(s->type != SOURCE_EXIT),1
))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("s->type != SOURCE_EXIT"), "../src/libsystemd/sd-event/sd-event.c"
, 2665, __PRETTY_FUNCTION__), 0))) return (-33); } while (0)
;
2666 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(s->event->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("s->event->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 2666, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
2667 assert_return(!event_pid_changed(s->event), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(s->event
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("!event_pid_changed(s->event)"), "../src/libsystemd/sd-event/sd-event.c"
, 2667, __PRETTY_FUNCTION__), 0))) return (-10); } while (0)
;
2668
2669 if (s->prepare == callback)
2670 return 0;
2671
2672 if (callback && s->prepare) {
2673 s->prepare = callback;
2674 return 0;
2675 }
2676
2677 r = prioq_ensure_allocated(&s->event->prepare, prepare_prioq_compare);
2678 if (r < 0)
2679 return r;
2680
2681 s->prepare = callback;
2682
2683 if (callback) {
2684 r = prioq_put(s->event->prepare, s, &s->prepare_index);
2685 if (r < 0)
2686 return r;
2687 } else
2688 prioq_remove(s->event->prepare, s, &s->prepare_index);
2689
2690 return 0;
2691}
2692
2693_public___attribute__ ((visibility("default"))) void* sd_event_source_get_userdata(sd_event_source *s) {
2694 assert_return(s, NULL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2694, __PRETTY_FUNCTION__), 0))) return (((void*)0)); } while
(0)
;
2695
2696 return s->userdata;
2697}
2698
2699_public___attribute__ ((visibility("default"))) void *sd_event_source_set_userdata(sd_event_source *s, void *userdata) {
2700 void *ret;
2701
2702 assert_return(s, NULL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2702, __PRETTY_FUNCTION__), 0))) return (((void*)0)); } while
(0)
;
2703
2704 ret = s->userdata;
2705 s->userdata = userdata;
2706
2707 return ret;
2708}
2709
2710static int event_source_enter_ratelimited(sd_event_source *s) {
2711 int r;
2712
2713 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2713, __PRETTY_FUNCTION__); } while (0)
;
2714
2715 /* When an event source becomes ratelimited, we place it in the CLOCK_MONOTONIC priority queue, with
2716 * the end of the rate limit time window, much as if it was a timer event source. */
2717
2718 if (s->ratelimited)
2719 return 0; /* Already ratelimited, this is a NOP hence */
2720
2721 /* Make sure we can install a CLOCK_MONOTONIC event further down. */
2722 r = setup_clock_data(s->event, &s->event->monotonic, CLOCK_MONOTONIC1);
2723 if (r < 0)
2724 return r;
2725
2726 /* Timer event sources are already using the earliest/latest queues for the timer scheduling. Let's
2727 * first remove them from the prioq appropriate for their own clock, so that we can use the prioq
2728 * fields of the event source then for adding it to the CLOCK_MONOTONIC prioq instead. */
2729 if (EVENT_SOURCE_IS_TIME(s->type)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; })
)
2730 event_source_time_prioq_remove(s, event_get_clock_data(s->event, s->type));
2731
2732 /* Now, let's add the event source to the monotonic clock instead */
2733 r = event_source_time_prioq_put(s, &s->event->monotonic);
2734 if (r < 0)
2735 goto fail;
2736
2737 /* And let's take the event source officially offline */
2738 r = event_source_offline(s, s->enabled, /* ratelimited= */ true1);
2739 if (r < 0) {
2740 event_source_time_prioq_remove(s, &s->event->monotonic);
2741 goto fail;
2742 }
2743
2744 event_source_pp_prioq_reshuffle(s);
2745
2746 log_debug("Event source %p (%s) entered rate limit state.", s, strna(s->description))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-event/sd-event.c", 2746, __func__, "Event source %p (%s) entered rate limit state."
, s, strna(s->description)) : -abs(_e); })
;
2747 return 0;
2748
2749fail:
2750 /* Reinstall time event sources in the priority queue as before. This shouldn't fail, since the queue
2751 * space for it should already be allocated. */
2752 if (EVENT_SOURCE_IS_TIME(s->type)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; })
)
2753 assert_se(event_source_time_prioq_put(s, event_get_clock_data(s->event, s->type)) >= 0)do { if ((__builtin_expect(!!(!(event_source_time_prioq_put(s
, event_get_clock_data(s->event, s->type)) >= 0)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("event_source_time_prioq_put(s, event_get_clock_data(s->event, s->type)) >= 0"
), "../src/libsystemd/sd-event/sd-event.c", 2753, __PRETTY_FUNCTION__
); } while (0)
;
2754
2755 return r;
2756}
2757
2758static int event_source_leave_ratelimit(sd_event_source *s) {
2759 int r;
2760
2761 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2761, __PRETTY_FUNCTION__); } while (0)
;
2762
2763 if (!s->ratelimited)
2764 return 0;
2765
2766 /* Let's take the event source out of the monotonic prioq first. */
2767 event_source_time_prioq_remove(s, &s->event->monotonic);
2768
2769 /* Let's then add the event source to its native clock prioq again — if this is a timer event source */
2770 if (EVENT_SOURCE_IS_TIME(s->type)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; })
) {
2771 r = event_source_time_prioq_put(s, event_get_clock_data(s->event, s->type));
2772 if (r < 0)
2773 goto fail;
2774 }
2775
2776 /* Let's try to take it online again. */
2777 r = event_source_online(s, s->enabled, /* ratelimited= */ false0);
2778 if (r < 0) {
2779 /* Do something roughly sensible when this failed: undo the two prioq ops above */
2780 if (EVENT_SOURCE_IS_TIME(s->type)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
})/sizeof(int)]; switch((s->type)) { case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
_found = 1; break; default: break; } _found; })
)
2781 event_source_time_prioq_remove(s, event_get_clock_data(s->event, s->type));
2782
2783 goto fail;
2784 }
2785
2786 event_source_pp_prioq_reshuffle(s);
2787 ratelimit_reset(&s->rate_limit);
2788
2789 log_debug("Event source %p (%s) left rate limit state.", s, strna(s->description))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-event/sd-event.c", 2789, __func__, "Event source %p (%s) left rate limit state."
, s, strna(s->description)) : -abs(_e); })
;
2790 return 0;
2791
2792fail:
2793 /* Do something somewhat reasonable when we cannot move an event sources out of ratelimited mode:
2794 * simply put it back in it, maybe we can then process it more successfully next iteration. */
2795 assert_se(event_source_time_prioq_put(s, &s->event->monotonic) >= 0)do { if ((__builtin_expect(!!(!(event_source_time_prioq_put(s
, &s->event->monotonic) >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("event_source_time_prioq_put(s, &s->event->monotonic) >= 0"
), "../src/libsystemd/sd-event/sd-event.c", 2795, __PRETTY_FUNCTION__
); } while (0)
;
2796
2797 return r;
2798}
2799
2800static usec_t sleep_between(sd_event *e, usec_t a, usec_t b) {
2801 usec_t c;
2802 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 2802, __PRETTY_FUNCTION__); } while (0)
;
2803 assert(a <= b)do { if ((__builtin_expect(!!(!(a <= b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("a <= b"), "../src/libsystemd/sd-event/sd-event.c"
, 2803, __PRETTY_FUNCTION__); } while (0)
;
2804
2805 if (a <= 0)
2806 return 0;
2807 if (a >= USEC_INFINITY((usec_t) -1))
2808 return USEC_INFINITY((usec_t) -1);
2809
2810 if (b <= a + 1)
2811 return a;
2812
2813 initialize_perturb(e);
2814
2815 /*
2816 Find a good time to wake up again between times a and b. We
2817 have two goals here:
2818
2819 a) We want to wake up as seldom as possible, hence prefer
2820 later times over earlier times.
2821
2822 b) But if we have to wake up, then let's make sure to
2823 dispatch as much as possible on the entire system.
2824
2825 We implement this by waking up everywhere at the same time
2826 within any given minute if we can, synchronised via the
2827 perturbation value determined from the boot ID. If we can't,
2828 then we try to find the same spot in every 10s, then 1s and
2829 then 250ms step. Otherwise, we pick the last possible time
2830 to wake up.
2831 */
2832
2833 c = (b / USEC_PER_MINUTE((usec_t) (60ULL*((usec_t) 1000000ULL)))) * USEC_PER_MINUTE((usec_t) (60ULL*((usec_t) 1000000ULL))) + e->perturb;
2834 if (c >= b) {
2835 if (_unlikely_(c < USEC_PER_MINUTE)(__builtin_expect(!!(c < ((usec_t) (60ULL*((usec_t) 1000000ULL
)))),0))
)
2836 return b;
2837
2838 c -= USEC_PER_MINUTE((usec_t) (60ULL*((usec_t) 1000000ULL)));
2839 }
2840
2841 if (c >= a)
2842 return c;
2843
2844 c = (b / (USEC_PER_SEC((usec_t) 1000000ULL)*10)) * (USEC_PER_SEC((usec_t) 1000000ULL)*10) + (e->perturb % (USEC_PER_SEC((usec_t) 1000000ULL)*10));
2845 if (c >= b) {
2846 if (_unlikely_(c < USEC_PER_SEC*10)(__builtin_expect(!!(c < ((usec_t) 1000000ULL)*10),0)))
2847 return b;
2848
2849 c -= USEC_PER_SEC((usec_t) 1000000ULL)*10;
2850 }
2851
2852 if (c >= a)
2853 return c;
2854
2855 c = (b / USEC_PER_SEC((usec_t) 1000000ULL)) * USEC_PER_SEC((usec_t) 1000000ULL) + (e->perturb % USEC_PER_SEC((usec_t) 1000000ULL));
2856 if (c >= b) {
2857 if (_unlikely_(c < USEC_PER_SEC)(__builtin_expect(!!(c < ((usec_t) 1000000ULL)),0)))
2858 return b;
2859
2860 c -= USEC_PER_SEC((usec_t) 1000000ULL);
2861 }
2862
2863 if (c >= a)
2864 return c;
2865
2866 c = (b / (USEC_PER_MSEC((usec_t) 1000ULL)*250)) * (USEC_PER_MSEC((usec_t) 1000ULL)*250) + (e->perturb % (USEC_PER_MSEC((usec_t) 1000ULL)*250));
2867 if (c >= b) {
2868 if (_unlikely_(c < USEC_PER_MSEC*250)(__builtin_expect(!!(c < ((usec_t) 1000ULL)*250),0)))
2869 return b;
2870
2871 c -= USEC_PER_MSEC((usec_t) 1000ULL)*250;
2872 }
2873
2874 if (c >= a)
2875 return c;
2876
2877 return b;
2878}
2879
2880static int event_arm_timer(
2881 sd_event *e,
2882 struct clock_data *d) {
2883
2884 struct itimerspec its = {};
2885 sd_event_source *a, *b;
2886 usec_t t;
2887 int r;
2888
2889 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 2889, __PRETTY_FUNCTION__); } while (0)
;
2890 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 2890, __PRETTY_FUNCTION__); } while (0)
;
2891
2892 if (!d->needs_rearm)
2893 return 0;
2894 else
2895 d->needs_rearm = false0;
2896
2897 a = prioq_peek(d->earliest);
2898 if (!a || a->enabled == SD_EVENT_OFF || time_event_source_next(a) == USEC_INFINITY((usec_t) -1)) {
2899
2900 if (d->fd < 0)
2901 return 0;
2902
2903 if (d->next == USEC_INFINITY((usec_t) -1))
2904 return 0;
2905
2906 /* disarm */
2907 r = timerfd_settime(d->fd, TFD_TIMER_ABSTIMETFD_TIMER_ABSTIME, &its, NULL((void*)0));
2908 if (r < 0)
2909 return r;
2910
2911 d->next = USEC_INFINITY((usec_t) -1);
2912 return 0;
2913 }
2914
2915 b = prioq_peek(d->latest);
2916 assert_se(b && b->enabled != SD_EVENT_OFF)do { if ((__builtin_expect(!!(!(b && b->enabled !=
SD_EVENT_OFF)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("b && b->enabled != SD_EVENT_OFF"), "../src/libsystemd/sd-event/sd-event.c"
, 2916, __PRETTY_FUNCTION__); } while (0)
;
2917
2918 t = sleep_between(e, time_event_source_next(a), time_event_source_latest(b));
2919 if (d->next == t)
2920 return 0;
2921
2922 assert_se(d->fd >= 0)do { if ((__builtin_expect(!!(!(d->fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d->fd >= 0"), "../src/libsystemd/sd-event/sd-event.c"
, 2922, __PRETTY_FUNCTION__); } while (0)
;
2923
2924 if (t == 0) {
2925 /* We don' want to disarm here, just mean some time looooong ago. */
2926 its.it_value.tv_sec = 0;
2927 its.it_value.tv_nsec = 1;
2928 } else
2929 timespec_store(&its.it_value, t);
2930
2931 r = timerfd_settime(d->fd, TFD_TIMER_ABSTIMETFD_TIMER_ABSTIME, &its, NULL((void*)0));
2932 if (r < 0)
2933 return -errno(*__errno_location ());
2934
2935 d->next = t;
2936 return 0;
2937}
2938
2939static int process_io(sd_event *e, sd_event_source *s, uint32_t revents) {
2940 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 2940, __PRETTY_FUNCTION__); } while (0)
;
2941 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 2941, __PRETTY_FUNCTION__); } while (0)
;
2942 assert(s->type == SOURCE_IO)do { if ((__builtin_expect(!!(!(s->type == SOURCE_IO)),0))
) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->type == SOURCE_IO"
), "../src/libsystemd/sd-event/sd-event.c", 2942, __PRETTY_FUNCTION__
); } while (0)
;
2943
2944 /* If the event source was already pending, we just OR in the
2945 * new revents, otherwise we reset the value. The ORing is
2946 * necessary to handle EPOLLONESHOT events properly where
2947 * readability might happen independently of writability, and
2948 * we need to keep track of both */
2949
2950 if (s->pending)
2951 s->io.revents |= revents;
2952 else
2953 s->io.revents = revents;
2954
2955 return source_set_pending(s, true1);
2956}
2957
2958static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) {
2959 uint64_t x;
2960 ssize_t ss;
2961
2962 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 2962, __PRETTY_FUNCTION__); } while (0)
;
2963 assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/libsystemd/sd-event/sd-event.c"
, 2963, __PRETTY_FUNCTION__); } while (0)
;
2964
2965 assert_return(events == EPOLLIN, -EIO)do { if (!(((__builtin_expect(!!(events == EPOLLIN),1))) ? (1
) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("events == EPOLLIN"
), "../src/libsystemd/sd-event/sd-event.c", 2965, __PRETTY_FUNCTION__
), 0))) return (-5); } while (0)
;
2966
2967 ss = read(fd, &x, sizeof(x));
2968 if (ss < 0) {
2969 if (IN_SET(errno, EAGAIN, EINTR)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){11, 4})/sizeof(int)]; switch((*__errno_location
())) { case 11: case 4: _found = 1; break; default: break; }
_found; })
)
2970 return 0;
2971
2972 return -errno(*__errno_location ());
2973 }
2974
2975 if (_unlikely_(ss != sizeof(x))(__builtin_expect(!!(ss != sizeof(x)),0)))
2976 return -EIO5;
2977
2978 if (next)
2979 *next = USEC_INFINITY((usec_t) -1);
2980
2981 return 0;
2982}
2983
2984static int process_timer(
2985 sd_event *e,
2986 usec_t n,
2987 struct clock_data *d) {
2988
2989 sd_event_source *s;
2990 int r;
2991
2992 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 2992, __PRETTY_FUNCTION__); } while (0)
;
2993 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 2993, __PRETTY_FUNCTION__); } while (0)
;
2994
2995 for (;;) {
2996 s = prioq_peek(d->earliest);
2997 if (!s || time_event_source_next(s) > n)
2998 break;
2999
3000 if (s->ratelimited) {
3001 /* This is an event sources whose ratelimit window has ended. Let's turn it on
3002 * again. */
3003 assert(s->ratelimited)do { if ((__builtin_expect(!!(!(s->ratelimited)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s->ratelimited"), "../src/libsystemd/sd-event/sd-event.c"
, 3003, __PRETTY_FUNCTION__); } while (0)
;
3004
3005 r = event_source_leave_ratelimit(s);
3006 if (r < 0)
3007 return r;
3008
3009 continue;
3010 }
3011
3012 if (s->enabled == SD_EVENT_OFF || s->pending)
3013 break;
3014
3015 r = source_set_pending(s, true1);
3016 if (r < 0)
3017 return r;
3018
3019 event_source_time_prioq_reshuffle(s);
3020 }
3021
3022 return 0;
3023}
3024
3025static int process_child(sd_event *e) {
3026 sd_event_source *s;
3027 Iterator i;
3028 int r;
3029
3030 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3030, __PRETTY_FUNCTION__); } while (0)
;
3031
3032 e->need_process_child = false0;
3033
3034 /*
3035 So, this is ugly. We iteratively invoke waitid() with P_PID
3036 + WNOHANG for each PID we wait for, instead of using
3037 P_ALL. This is because we only want to get child
3038 information of very specific child processes, and not all
3039 of them. We might not have processed the SIGCHLD even of a
3040 previous invocation and we don't want to maintain a
3041 unbounded *per-child* event queue, hence we really don't
3042 want anything flushed out of the kernel's queue that we
3043 don't care about. Since this is O(n) this means that if you
3044 have a lot of processes you probably want to handle SIGCHLD
3045 yourself.
3046
3047 We do not reap the children here (by using WNOWAIT), this
3048 is only done after the event source is dispatched so that
3049 the callback still sees the process as a zombie.
3050 */
3051
3052 HASHMAP_FOREACH(s, e->child_sources, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((e->child_sources
), &(i), (void**)&(s), ((void*)0)); )
{
3053 assert(s->type == SOURCE_CHILD)do { if ((__builtin_expect(!!(!(s->type == SOURCE_CHILD)),
0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->type == SOURCE_CHILD"
), "../src/libsystemd/sd-event/sd-event.c", 3053, __PRETTY_FUNCTION__
); } while (0)
;
3054
3055 if (s->pending)
3056 continue;
3057
3058 if (event_source_is_offline(s))
3059 continue;
3060
3061 zero(s->child.siginfo)(({ size_t _l_ = (sizeof(s->child.siginfo)); void *_x_ = (
&(s->child.siginfo)); _l_ == 0 ? _x_ : memset(_x_, 0, _l_
); }))
;
3062 r = waitid(P_PID, s->child.pid, &s->child.siginfo,
3063 WNOHANG1 | (s->child.options & WEXITED4 ? WNOWAIT0x01000000 : 0) | s->child.options);
3064 if (r < 0)
3065 return -errno(*__errno_location ());
3066
3067 if (s->child.siginfo.si_pid_sifields._kill.si_pid != 0) {
3068 bool_Bool zombie = IN_SET(s->child.siginfo.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){CLD_EXITED, CLD_KILLED, CLD_DUMPED})/sizeof
(int)]; switch(s->child.siginfo.si_code) { case CLD_EXITED
: case CLD_KILLED: case CLD_DUMPED: _found = 1; break; default
: break; } _found; })
;
3069
3070 if (!zombie && (s->child.options & WEXITED4)) {
3071 /* If the child isn't dead then let's
3072 * immediately remove the state change
3073 * from the queue, since there's no
3074 * benefit in leaving it queued */
3075
3076 assert(s->child.options & (WSTOPPED|WCONTINUED))do { if ((__builtin_expect(!!(!(s->child.options & (2|
8))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->child.options & (WSTOPPED|WCONTINUED)"
), "../src/libsystemd/sd-event/sd-event.c", 3076, __PRETTY_FUNCTION__
); } while (0)
;
3077 waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG1|(s->child.options & (WSTOPPED2|WCONTINUED8)));
3078 }
3079
3080 r = source_set_pending(s, true1);
3081 if (r < 0)
3082 return r;
3083 }
3084 }
3085
3086 return 0;
3087}
3088
3089static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
3090 bool_Bool read_one = false0;
3091 int r;
3092
3093 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3093, __PRETTY_FUNCTION__); } while (0)
;
3094 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 3094, __PRETTY_FUNCTION__); } while (0)
;
3095 assert_return(events == EPOLLIN, -EIO)do { if (!(((__builtin_expect(!!(events == EPOLLIN),1))) ? (1
) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("events == EPOLLIN"
), "../src/libsystemd/sd-event/sd-event.c", 3095, __PRETTY_FUNCTION__
), 0))) return (-5); } while (0)
;
3096
3097 /* If there's a signal queued on this priority and SIGCHLD is
3098 on this priority too, then make sure to recheck the
3099 children we watch. This is because we only ever dequeue
3100 the first signal per priority, and if we dequeue one, and
3101 SIGCHLD might be enqueued later we wouldn't know, but we
3102 might have higher priority children we care about hence we
3103 need to check that explicitly. */
3104
3105 if (sigismember(&d->sigset, SIGCHLD17))
3106 e->need_process_child = true1;
3107
3108 /* If there's already an event source pending for this
3109 * priority we don't read another */
3110 if (d->current)
3111 return 0;
3112
3113 for (;;) {
3114 struct signalfd_siginfo si;
3115 ssize_t n;
3116 sd_event_source *s = NULL((void*)0);
3117
3118 n = read(d->fd, &si, sizeof(si));
3119 if (n < 0) {
3120 if (IN_SET(errno, EAGAIN, EINTR)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){11, 4})/sizeof(int)]; switch((*__errno_location
())) { case 11: case 4: _found = 1; break; default: break; }
_found; })
)
3121 return read_one;
3122
3123 return -errno(*__errno_location ());
3124 }
3125
3126 if (_unlikely_(n != sizeof(si))(__builtin_expect(!!(n != sizeof(si)),0)))
3127 return -EIO5;
3128
3129 assert(SIGNAL_VALID(si.ssi_signo))do { if ((__builtin_expect(!!(!(SIGNAL_VALID(si.ssi_signo))),
0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("SIGNAL_VALID(si.ssi_signo)"
), "../src/libsystemd/sd-event/sd-event.c", 3129, __PRETTY_FUNCTION__
); } while (0)
;
3130
3131 read_one = true1;
3132
3133 if (e->signal_sources)
3134 s = e->signal_sources[si.ssi_signo];
3135 if (!s)
3136 continue;
3137 if (s->pending)
3138 continue;
3139
3140 s->signal.siginfo = si;
3141 d->current = s;
3142
3143 r = source_set_pending(s, true1);
3144 if (r < 0)
3145 return r;
3146
3147 return 1;
3148 }
3149}
3150
3151static int event_inotify_data_read(sd_event *e, struct inotify_data *d, uint32_t revents) {
3152 ssize_t n;
3153
3154 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3154, __PRETTY_FUNCTION__); } while (0)
;
3155 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 3155, __PRETTY_FUNCTION__); } while (0)
;
3156
3157 assert_return(revents == EPOLLIN, -EIO)do { if (!(((__builtin_expect(!!(revents == EPOLLIN),1))) ? (
1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("revents == EPOLLIN"
), "../src/libsystemd/sd-event/sd-event.c", 3157, __PRETTY_FUNCTION__
), 0))) return (-5); } while (0)
;
3158
3159 /* If there's already an event source pending for this priority, don't read another */
3160 if (d->n_pending > 0)
3161 return 0;
3162
3163 /* Is the read buffer non-empty? If so, let's not read more */
3164 if (d->buffer_filled > 0)
3165 return 0;
3166
3167 n = read(d->fd, &d->buffer, sizeof(d->buffer));
3168 if (n < 0) {
3169 if (IN_SET(errno, EAGAIN, EINTR)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){11, 4})/sizeof(int)]; switch((*__errno_location
())) { case 11: case 4: _found = 1; break; default: break; }
_found; })
)
3170 return 0;
3171
3172 return -errno(*__errno_location ());
3173 }
3174
3175 assert(n > 0)do { if ((__builtin_expect(!!(!(n > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("n > 0"), "../src/libsystemd/sd-event/sd-event.c"
, 3175, __PRETTY_FUNCTION__); } while (0)
;
3176 d->buffer_filled = (size_t) n;
3177 LIST_PREPEND(buffered, e->inotify_data_buffered, d)do { typeof(*(e->inotify_data_buffered)) **_head = &(e
->inotify_data_buffered), *_item = (d); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd/sd-event/sd-event.c", 3177, __PRETTY_FUNCTION__
); } while (0); if ((_item->buffered_next = *_head)) _item
->buffered_next->buffered_prev = _item; _item->buffered_prev
= ((void*)0); *_head = _item; } while (0)
;
3178
3179 return 1;
3180}
3181
3182static void event_inotify_data_drop(sd_event *e, struct inotify_data *d, size_t sz) {
3183 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3183, __PRETTY_FUNCTION__); } while (0)
;
3184 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 3184, __PRETTY_FUNCTION__); } while (0)
;
3185 assert(sz <= d->buffer_filled)do { if ((__builtin_expect(!!(!(sz <= d->buffer_filled)
),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("sz <= d->buffer_filled"
), "../src/libsystemd/sd-event/sd-event.c", 3185, __PRETTY_FUNCTION__
); } while (0)
;
3186
3187 if (sz == 0)
3188 return;
3189
3190 /* Move the rest to the buffer to the front, in order to get things properly aligned again */
3191 memmove(d->buffer.raw, d->buffer.raw + sz, d->buffer_filled - sz);
3192 d->buffer_filled -= sz;
3193
3194 if (d->buffer_filled == 0)
3195 LIST_REMOVE(buffered, e->inotify_data_buffered, d)do { typeof(*(e->inotify_data_buffered)) **_head = &(e
->inotify_data_buffered), *_item = (d); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd/sd-event/sd-event.c", 3195, __PRETTY_FUNCTION__
); } while (0); if (_item->buffered_next) _item->buffered_next
->buffered_prev = _item->buffered_prev; if (_item->buffered_prev
) _item->buffered_prev->buffered_next = _item->buffered_next
; else { do { if ((__builtin_expect(!!(!(*_head == _item)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*_head == _item"
), "../src/libsystemd/sd-event/sd-event.c", 3195, __PRETTY_FUNCTION__
); } while (0); *_head = _item->buffered_next; } _item->
buffered_next = _item->buffered_prev = ((void*)0); } while
(0)
;
3196}
3197
3198static int event_inotify_data_process(sd_event *e, struct inotify_data *d) {
3199 int r;
3200
3201 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3201, __PRETTY_FUNCTION__); } while (0)
;
3202 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/libsystemd/sd-event/sd-event.c"
, 3202, __PRETTY_FUNCTION__); } while (0)
;
3203
3204 /* If there's already an event source pending for this priority, don't read another */
3205 if (d->n_pending > 0)
3206 return 0;
3207
3208 while (d->buffer_filled > 0) {
3209 size_t sz;
3210
3211 /* Let's validate that the event structures are complete */
3212 if (d->buffer_filled < offsetof(struct inotify_event, name)__builtin_offsetof(struct inotify_event, name))
3213 return -EIO5;
3214
3215 sz = offsetof(struct inotify_event, name)__builtin_offsetof(struct inotify_event, name) + d->buffer.ev.len;
3216 if (d->buffer_filled < sz)
3217 return -EIO5;
3218
3219 if (d->buffer.ev.mask & IN_Q_OVERFLOW0x00004000) {
3220 struct inode_data *inode_data;
3221 Iterator i;
3222
3223 /* The queue overran, let's pass this event to all event sources connected to this inotify
3224 * object */
3225
3226 HASHMAP_FOREACH(inode_data, d->inodes, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((d->inodes), &
(i), (void**)&(inode_data), ((void*)0)); )
{
3227 sd_event_source *s;
3228
3229 LIST_FOREACH(inotify.by_inode_data, s, inode_data->event_sources)for ((s) = (inode_data->event_sources); (s); (s) = (s)->
inotify.by_inode_data_next)
{
3230
3231 if (event_source_is_offline(s))
3232 continue;
3233
3234 r = source_set_pending(s, true1);
3235 if (r < 0)
3236 return r;
3237 }
3238 }
3239 } else {
3240 struct inode_data *inode_data;
3241 sd_event_source *s;
3242
3243 /* Find the inode object for this watch descriptor. If IN_IGNORED is set we also remove it from
3244 * our watch descriptor table. */
3245 if (d->buffer.ev.mask & IN_IGNORED0x00008000) {
3246
3247 inode_data = hashmap_remove(d->wd, INT_TO_PTR(d->buffer.ev.wd)((void *) ((intptr_t) (d->buffer.ev.wd))));
3248 if (!inode_data) {
3249 event_inotify_data_drop(e, d, sz);
3250 continue;
3251 }
3252
3253 /* The watch descriptor was removed by the kernel, let's drop it here too */
3254 inode_data->wd = -1;
3255 } else {
3256 inode_data = hashmap_get(d->wd, INT_TO_PTR(d->buffer.ev.wd)((void *) ((intptr_t) (d->buffer.ev.wd))));
3257 if (!inode_data) {
3258 event_inotify_data_drop(e, d, sz);
3259 continue;
3260 }
3261 }
3262
3263 /* Trigger all event sources that are interested in these events. Also trigger all event
3264 * sources if IN_IGNORED or IN_UNMOUNT is set. */
3265 LIST_FOREACH(inotify.by_inode_data, s, inode_data->event_sources)for ((s) = (inode_data->event_sources); (s); (s) = (s)->
inotify.by_inode_data_next)
{
3266
3267 if (event_source_is_offline(s))
3268 continue;
3269
3270 if ((d->buffer.ev.mask & (IN_IGNORED0x00008000|IN_UNMOUNT0x00002000)) == 0 &&
3271 (s->inotify.mask & d->buffer.ev.mask & IN_ALL_EVENTS(0x00000001 | 0x00000002 | 0x00000004 | 0x00000008 | 0x00000010
| 0x00000020 | 0x00000040 | 0x00000080 | 0x00000100 | 0x00000200
| 0x00000400 | 0x00000800)
) == 0)
3272 continue;
3273
3274 r = source_set_pending(s, true1);
3275 if (r < 0)
3276 return r;
3277 }
3278 }
3279
3280 /* Something pending now? If so, let's finish, otherwise let's read more. */
3281 if (d->n_pending > 0)
3282 return 1;
3283 }
3284
3285 return 0;
3286}
3287
3288static int process_inotify(sd_event *e) {
3289 struct inotify_data *d;
3290 int r, done = 0;
3291
3292 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3292, __PRETTY_FUNCTION__); } while (0)
;
3293
3294 LIST_FOREACH(buffered, d, e->inotify_data_buffered)for ((d) = (e->inotify_data_buffered); (d); (d) = (d)->
buffered_next)
{
3295 r = event_inotify_data_process(e, d);
3296 if (r < 0)
3297 return r;
3298 if (r > 0)
3299 done ++;
3300 }
3301
3302 return done;
3303}
3304
3305static int source_dispatch(sd_event_source *s) {
3306 _cleanup_(sd_event_unrefp)__attribute__((cleanup(sd_event_unrefp))) sd_event *saved_event = NULL((void*)0);
3307 EventSourceType saved_type;
3308 int r = 0;
3309
3310 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 3310, __PRETTY_FUNCTION__); } while (0)
;
3311 assert(s->pending || s->type == SOURCE_EXIT)do { if ((__builtin_expect(!!(!(s->pending || s->type ==
SOURCE_EXIT)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("s->pending || s->type == SOURCE_EXIT"), "../src/libsystemd/sd-event/sd-event.c"
, 3311, __PRETTY_FUNCTION__); } while (0)
;
3312
3313 /* Save the event source type, here, so that we still know it after the event callback which might invalidate
3314 * the event. */
3315 saved_type = s->type;
3316
3317 /* Similar, store a reference to the event loop object, so that we can still access it after the
3318 * callback might have invalidated/disconnected the event source. */
3319 saved_event = sd_event_ref(s->event);
3320
3321 /* Check if we hit the ratelimit for this event source, if so, let's disable it. */
3322 assert(!s->ratelimited)do { if ((__builtin_expect(!!(!(!s->ratelimited)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!s->ratelimited"), "../src/libsystemd/sd-event/sd-event.c"
, 3322, __PRETTY_FUNCTION__); } while (0)
;
3323 if (!ratelimit_below(&s->rate_limit)) {
3324 r = event_source_enter_ratelimited(s);
3325 if (r < 0)
3326 return r;
3327
3328 return 1;
3329 }
3330
3331 if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_DEFER, SOURCE_EXIT})/sizeof(int)]
; switch(s->type) { case SOURCE_DEFER: case SOURCE_EXIT: _found
= 1; break; default: break; } _found; })
) {
3332 r = source_set_pending(s, false0);
3333 if (r < 0)
3334 return r;
3335 }
3336
3337 if (s->type != SOURCE_POST) {
3338 sd_event_source *z;
3339 Iterator i;
3340
3341 /* If we execute a non-post source, let's mark all
3342 * post sources as pending */
3343
3344 SET_FOREACH(z, s->event->post_sources, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); set_iterate((s->event->post_sources
), &(i), (void**)&(z)); )
{
3345 if (z->enabled == SD_EVENT_OFF)
3346 continue;
3347
3348 r = source_set_pending(z, true1);
3349 if (r < 0)
3350 return r;
3351 }
3352 }
3353
3354 if (s->enabled == SD_EVENT_ONESHOT) {
3355 r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
3356 if (r < 0)
3357 return r;
3358 }
3359
3360 s->dispatching = true1;
3361
3362 switch (s->type) {
3363
3364 case SOURCE_IO:
3365 r = s->io.callback(s, s->io.fd, s->io.revents, s->userdata);
3366 break;
3367
3368 case SOURCE_TIME_REALTIME:
3369 case SOURCE_TIME_BOOTTIME:
3370 case SOURCE_TIME_MONOTONIC:
3371 case SOURCE_TIME_REALTIME_ALARM:
3372 case SOURCE_TIME_BOOTTIME_ALARM:
3373 r = s->time.callback(s, s->time.next, s->userdata);
3374 break;
3375
3376 case SOURCE_SIGNAL:
3377 r = s->signal.callback(s, &s->signal.siginfo, s->userdata);
3378 break;
3379
3380 case SOURCE_CHILD: {
3381 bool_Bool zombie;
3382
3383 zombie = IN_SET(s->child.siginfo.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){CLD_EXITED, CLD_KILLED, CLD_DUMPED})/sizeof
(int)]; switch(s->child.siginfo.si_code) { case CLD_EXITED
: case CLD_KILLED: case CLD_DUMPED: _found = 1; break; default
: break; } _found; })
;
3384
3385 r = s->child.callback(s, &s->child.siginfo, s->userdata);
3386
3387 /* Now, reap the PID for good. */
3388 if (zombie)
3389 (void) waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG1|WEXITED4);
3390
3391 break;
3392 }
3393
3394 case SOURCE_DEFER:
3395 r = s->defer.callback(s, s->userdata);
3396 break;
3397
3398 case SOURCE_POST:
3399 r = s->post.callback(s, s->userdata);
3400 break;
3401
3402 case SOURCE_EXIT:
3403 r = s->exit.callback(s, s->userdata);
3404 break;
3405
3406 case SOURCE_INOTIFY: {
3407 struct sd_event *e = s->event;
3408 struct inotify_data *d;
3409 size_t sz;
3410
3411 assert(s->inotify.inode_data)do { if ((__builtin_expect(!!(!(s->inotify.inode_data)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->inotify.inode_data"
), "../src/libsystemd/sd-event/sd-event.c", 3411, __PRETTY_FUNCTION__
); } while (0)
;
3412 assert_se(d = s->inotify.inode_data->inotify_data)do { if ((__builtin_expect(!!(!(d = s->inotify.inode_data->
inotify_data)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("d = s->inotify.inode_data->inotify_data"), "../src/libsystemd/sd-event/sd-event.c"
, 3412, __PRETTY_FUNCTION__); } while (0)
;
3413
3414 assert(d->buffer_filled >= offsetof(struct inotify_event, name))do { if ((__builtin_expect(!!(!(d->buffer_filled >= __builtin_offsetof
(struct inotify_event, name))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("d->buffer_filled >= offsetof(struct inotify_event, name)"
), "../src/libsystemd/sd-event/sd-event.c", 3414, __PRETTY_FUNCTION__
); } while (0)
;
3415 sz = offsetof(struct inotify_event, name)__builtin_offsetof(struct inotify_event, name) + d->buffer.ev.len;
3416 assert(d->buffer_filled >= sz)do { if ((__builtin_expect(!!(!(d->buffer_filled >= sz)
),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("d->buffer_filled >= sz"
), "../src/libsystemd/sd-event/sd-event.c", 3416, __PRETTY_FUNCTION__
); } while (0)
;
3417
3418 r = s->inotify.callback(s, &d->buffer.ev, s->userdata);
3419
3420 /* When no event is pending anymore on this inotify object, then let's drop the event from the
3421 * buffer. */
3422 if (d->n_pending == 0)
3423 event_inotify_data_drop(e, d, sz);
3424
3425 break;
3426 }
3427
3428 case SOURCE_WATCHDOG:
3429 case _SOURCE_EVENT_SOURCE_TYPE_MAX:
3430 case _SOURCE_EVENT_SOURCE_TYPE_INVALID:
3431 assert_not_reached("Wut? I shouldn't exist.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Wut? I shouldn't exist."), "../src/libsystemd/sd-event/sd-event.c"
, 3431, __PRETTY_FUNCTION__); } while (0)
;
3432 }
3433
3434 s->dispatching = false0;
3435
3436 if (r < 0)
3437 log_debug_errno(r, "Event source %s (type %s) returned error, disabling: %m",({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-event/sd-event.c", 3438, __func__, "Event source %s (type %s) returned error, disabling: %m"
, strna(s->description), event_source_type_to_string(saved_type
)) : -abs(_e); })
3438 strna(s->description), event_source_type_to_string(saved_type))({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-event/sd-event.c", 3438, __func__, "Event source %s (type %s) returned error, disabling: %m"
, strna(s->description), event_source_type_to_string(saved_type
)) : -abs(_e); })
;
3439
3440 if (s->n_ref == 0)
3441 source_free(s);
3442 else if (r < 0)
3443 sd_event_source_set_enabled(s, SD_EVENT_OFF);
3444
3445 return 1;
3446}
3447
3448static int event_prepare(sd_event *e) {
3449 int r;
3450
3451 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3451, __PRETTY_FUNCTION__); } while (0)
;
3452
3453 for (;;) {
3454 sd_event_source *s;
3455
3456 s = prioq_peek(e->prepare);
3457 if (!s || s->prepare_iteration == e->iteration || event_source_is_offline(s))
3458 break;
3459
3460 s->prepare_iteration = e->iteration;
3461 r = prioq_reshuffle(e->prepare, s, &s->prepare_index);
3462 if (r < 0)
3463 return r;
3464
3465 assert(s->prepare)do { if ((__builtin_expect(!!(!(s->prepare)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s->prepare"), "../src/libsystemd/sd-event/sd-event.c"
, 3465, __PRETTY_FUNCTION__); } while (0)
;
3466
3467 s->dispatching = true1;
3468 r = s->prepare(s, s->userdata);
3469 s->dispatching = false0;
3470
3471 if (r < 0)
3472 log_debug_errno(r, "Prepare callback of event source %s (type %s) returned error, disabling: %m",({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-event/sd-event.c", 3473, __func__, "Prepare callback of event source %s (type %s) returned error, disabling: %m"
, strna(s->description), event_source_type_to_string(s->
type)) : -abs(_e); })
3473 strna(s->description), event_source_type_to_string(s->type))({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-event/sd-event.c", 3473, __func__, "Prepare callback of event source %s (type %s) returned error, disabling: %m"
, strna(s->description), event_source_type_to_string(s->
type)) : -abs(_e); })
;
3474
3475 if (s->n_ref == 0)
3476 source_free(s);
3477 else if (r < 0)
3478 sd_event_source_set_enabled(s, SD_EVENT_OFF);
3479 }
3480
3481 return 0;
3482}
3483
3484static int dispatch_exit(sd_event *e) {
3485 sd_event_source *p;
3486 int r;
3487
3488 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3488, __PRETTY_FUNCTION__); } while (0)
;
3489
3490 p = prioq_peek(e->exit);
3491 if (!p || event_source_is_offline(p)) {
3492 e->state = SD_EVENT_FINISHED;
3493 return 0;
3494 }
3495
3496 _unused___attribute__ ((unused)) _cleanup_(sd_event_unrefp)__attribute__((cleanup(sd_event_unrefp))) sd_event *ref = sd_event_ref(e);
3497 e->iteration++;
3498 e->state = SD_EVENT_EXITING;
3499 r = source_dispatch(p);
3500 e->state = SD_EVENT_INITIAL;
3501 return r;
3502}
3503
3504static sd_event_source* event_next_pending(sd_event *e) {
3505 sd_event_source *p;
3506
3507 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3507, __PRETTY_FUNCTION__); } while (0)
;
3508
3509 p = prioq_peek(e->pending);
3510 if (!p)
3511 return NULL((void*)0);
3512
3513 if (event_source_is_offline(p))
3514 return NULL((void*)0);
3515
3516 return p;
3517}
3518
3519static int arm_watchdog(sd_event *e) {
3520 struct itimerspec its = {};
3521 usec_t t;
3522 int r;
3523
3524 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3524, __PRETTY_FUNCTION__); } while (0)
;
3525 assert(e->watchdog_fd >= 0)do { if ((__builtin_expect(!!(!(e->watchdog_fd >= 0)),0
))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("e->watchdog_fd >= 0"
), "../src/libsystemd/sd-event/sd-event.c", 3525, __PRETTY_FUNCTION__
); } while (0)
;
3526
3527 t = sleep_between(e,
3528 e->watchdog_last + (e->watchdog_period / 2),
3529 e->watchdog_last + (e->watchdog_period * 3 / 4));
3530
3531 timespec_store(&its.it_value, t);
3532
3533 /* Make sure we never set the watchdog to 0, which tells the
3534 * kernel to disable it. */
3535 if (its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0)
3536 its.it_value.tv_nsec = 1;
3537
3538 r = timerfd_settime(e->watchdog_fd, TFD_TIMER_ABSTIMETFD_TIMER_ABSTIME, &its, NULL((void*)0));
3539 if (r < 0)
3540 return -errno(*__errno_location ());
3541
3542 return 0;
3543}
3544
3545static int process_watchdog(sd_event *e) {
3546 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3546, __PRETTY_FUNCTION__); } while (0)
;
3547
3548 if (!e->watchdog)
3549 return 0;
3550
3551 /* Don't notify watchdog too often */
3552 if (e->watchdog_last + e->watchdog_period / 4 > e->timestamp.monotonic)
3553 return 0;
3554
3555 sd_notify(false0, "WATCHDOG=1");
3556 e->watchdog_last = e->timestamp.monotonic;
3557
3558 return arm_watchdog(e);
3559}
3560
3561static void event_close_inode_data_fds(sd_event *e) {
3562 struct inode_data *d;
3563
3564 assert(e)do { if ((__builtin_expect(!!(!(e)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3564, __PRETTY_FUNCTION__); } while (0)
;
3565
3566 /* Close the fds pointing to the inodes to watch now. We need to close them as they might otherwise pin
3567 * filesystems. But we can't close them right-away as we need them as long as the user still wants to make
3568 * adjustments to the even source, such as changing the priority (which requires us to remove and readd a watch
3569 * for the inode). Hence, let's close them when entering the first iteration after they were added, as a
3570 * compromise. */
3571
3572 while ((d = e->inode_data_to_close)) {
3573 assert(d->fd >= 0)do { if ((__builtin_expect(!!(!(d->fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d->fd >= 0"), "../src/libsystemd/sd-event/sd-event.c"
, 3573, __PRETTY_FUNCTION__); } while (0)
;
3574 d->fd = safe_close(d->fd);
3575
3576 LIST_REMOVE(to_close, e->inode_data_to_close, d)do { typeof(*(e->inode_data_to_close)) **_head = &(e->
inode_data_to_close), *_item = (d); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/libsystemd/sd-event/sd-event.c", 3576, __PRETTY_FUNCTION__
); } while (0); if (_item->to_close_next) _item->to_close_next
->to_close_prev = _item->to_close_prev; if (_item->to_close_prev
) _item->to_close_prev->to_close_next = _item->to_close_next
; else { do { if ((__builtin_expect(!!(!(*_head == _item)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*_head == _item"
), "../src/libsystemd/sd-event/sd-event.c", 3576, __PRETTY_FUNCTION__
); } while (0); *_head = _item->to_close_next; } _item->
to_close_next = _item->to_close_prev = ((void*)0); } while
(0)
;
3577 }
3578}
3579
3580_public___attribute__ ((visibility("default"))) int sd_event_prepare(sd_event *e) {
3581 int r;
3582
3583 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3583, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3584 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3584, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
3585 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3585, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
3586 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 3586, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
3587 assert_return(e->state == SD_EVENT_INITIAL, -EBUSY)do { if (!(((__builtin_expect(!!(e->state == SD_EVENT_INITIAL
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state == SD_EVENT_INITIAL"), "../src/libsystemd/sd-event/sd-event.c"
, 3587, __PRETTY_FUNCTION__), 0))) return (-16); } while (0)
;
3588
3589 /* Let's check that if we are a default event loop we are executed in the correct thread. We only do
3590 * this check here once, since gettid() is typically not cached, and thus want to minimize
3591 * syscalls */
3592 assert_return(!e->default_event_ptr || e->tid == gettid(), -EREMOTEIO)do { if (!(((__builtin_expect(!!(!e->default_event_ptr || e
->tid == gettid()),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("!e->default_event_ptr || e->tid == gettid()"
), "../src/libsystemd/sd-event/sd-event.c", 3592, __PRETTY_FUNCTION__
), 0))) return (-121); } while (0)
;
3593
3594 /* Make sure that none of the preparation callbacks ends up freeing the event source under our feet */
3595 _unused___attribute__ ((unused)) _cleanup_(sd_event_unrefp)__attribute__((cleanup(sd_event_unrefp))) sd_event *ref = sd_event_ref(e);
3596
3597 if (e->exit_requested)
3598 goto pending;
3599
3600 e->iteration++;
3601
3602 e->state = SD_EVENT_PREPARING;
3603 r = event_prepare(e);
3604 e->state = SD_EVENT_INITIAL;
3605 if (r < 0)
3606 return r;
3607
3608 r = event_arm_timer(e, &e->realtime);
3609 if (r < 0)
3610 return r;
3611
3612 r = event_arm_timer(e, &e->boottime);
3613 if (r < 0)
3614 return r;
3615
3616 r = event_arm_timer(e, &e->monotonic);
3617 if (r < 0)
3618 return r;
3619
3620 r = event_arm_timer(e, &e->realtime_alarm);
3621 if (r < 0)
3622 return r;
3623
3624 r = event_arm_timer(e, &e->boottime_alarm);
3625 if (r < 0)
3626 return r;
3627
3628 event_close_inode_data_fds(e);
3629
3630 if (event_next_pending(e) || e->need_process_child)
3631 goto pending;
3632
3633 e->state = SD_EVENT_ARMED;
3634
3635 return 0;
3636
3637pending:
3638 e->state = SD_EVENT_ARMED;
3639 r = sd_event_wait(e, 0);
3640 if (r == 0)
3641 e->state = SD_EVENT_ARMED;
3642
3643 return r;
3644}
3645
3646_public___attribute__ ((visibility("default"))) int sd_event_wait(sd_event *e, uint64_t timeout) {
3647 struct epoll_event *ev_queue;
3648 unsigned ev_queue_max;
3649 int r, m, i;
3650
3651 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3651, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3652 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3652, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
3653 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3653, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
3654 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 3654, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
3655 assert_return(e->state == SD_EVENT_ARMED, -EBUSY)do { if (!(((__builtin_expect(!!(e->state == SD_EVENT_ARMED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state == SD_EVENT_ARMED"), "../src/libsystemd/sd-event/sd-event.c"
, 3655, __PRETTY_FUNCTION__), 0))) return (-16); } while (0)
;
3656
3657 if (e->exit_requested) {
3658 e->state = SD_EVENT_PENDING;
3659 return 1;
3660 }
3661
3662 ev_queue_max = MAX(e->n_sources, 1u)__extension__ ({ const typeof((e->n_sources)) __unique_prefix_A55
= ((e->n_sources)); const typeof((1u)) __unique_prefix_B56
= ((1u)); __unique_prefix_A55 > __unique_prefix_B56 ? __unique_prefix_A55
: __unique_prefix_B56; })
;
3663 ev_queue = newa(struct epoll_event, ev_queue_max)({ do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof
(struct epoll_event), ev_queue_max))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!size_multiply_overflow(sizeof(struct epoll_event), ev_queue_max)"
), "../src/libsystemd/sd-event/sd-event.c", 3663, __PRETTY_FUNCTION__
); } while (0); (struct epoll_event*) __builtin_alloca (sizeof
(struct epoll_event)*(ev_queue_max)); })
;
3664
3665 /* If we still have inotify data buffered, then query the other fds, but don't wait on it */
3666 if (e->inotify_data_buffered)
3667 timeout = 0;
3668
3669 m = epoll_wait(e->epoll_fd, ev_queue, ev_queue_max,
3670 timeout == (uint64_t) -1 ? -1 : (int) ((timeout + USEC_PER_MSEC((usec_t) 1000ULL) - 1) / USEC_PER_MSEC((usec_t) 1000ULL)));
3671 if (m < 0) {
3672 if (errno(*__errno_location ()) == EINTR4) {
3673 e->state = SD_EVENT_PENDING;
3674 return 1;
3675 }
3676
3677 r = -errno(*__errno_location ());
3678 goto finish;
3679 }
3680
3681 triple_timestamp_get(&e->timestamp);
3682
3683 for (i = 0; i < m; i++) {
3684
3685 if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_WATCHDOG)((void *) ((intptr_t) (SOURCE_WATCHDOG))))
3686 r = flush_timer(e, e->watchdog_fd, ev_queue[i].events, NULL((void*)0));
3687 else {
3688 WakeupType *t = ev_queue[i].data.ptr;
3689
3690 switch (*t) {
3691
3692 case WAKEUP_EVENT_SOURCE:
3693 r = process_io(e, ev_queue[i].data.ptr, ev_queue[i].events);
3694 break;
3695
3696 case WAKEUP_CLOCK_DATA: {
3697 struct clock_data *d = ev_queue[i].data.ptr;
3698 r = flush_timer(e, d->fd, ev_queue[i].events, &d->next);
3699 break;
3700 }
3701
3702 case WAKEUP_SIGNAL_DATA:
3703 r = process_signal(e, ev_queue[i].data.ptr, ev_queue[i].events);
3704 break;
3705
3706 case WAKEUP_INOTIFY_DATA:
3707 r = event_inotify_data_read(e, ev_queue[i].data.ptr, ev_queue[i].events);
3708 break;
3709
3710 default:
3711 assert_not_reached("Invalid wake-up pointer")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Invalid wake-up pointer"), "../src/libsystemd/sd-event/sd-event.c"
, 3711, __PRETTY_FUNCTION__); } while (0)
;
3712 }
3713 }
3714 if (r < 0)
3715 goto finish;
3716 }
3717
3718 r = process_watchdog(e);
3719 if (r < 0)
3720 goto finish;
3721
3722 r = process_timer(e, e->timestamp.realtime, &e->realtime);
3723 if (r < 0)
3724 goto finish;
3725
3726 r = process_timer(e, e->timestamp.boottime, &e->boottime);
3727 if (r < 0)
3728 goto finish;
3729
3730 r = process_timer(e, e->timestamp.monotonic, &e->monotonic);
3731 if (r < 0)
3732 goto finish;
3733
3734 r = process_timer(e, e->timestamp.realtime, &e->realtime_alarm);
3735 if (r < 0)
3736 goto finish;
3737
3738 r = process_timer(e, e->timestamp.boottime, &e->boottime_alarm);
3739 if (r < 0)
3740 goto finish;
3741
3742 if (e->need_process_child) {
3743 r = process_child(e);
3744 if (r < 0)
3745 goto finish;
3746 }
3747
3748 r = process_inotify(e);
3749 if (r < 0)
3750 goto finish;
3751
3752 if (event_next_pending(e)) {
3753 e->state = SD_EVENT_PENDING;
3754
3755 return 1;
3756 }
3757
3758 r = 0;
3759
3760finish:
3761 e->state = SD_EVENT_INITIAL;
3762
3763 return r;
3764}
3765
3766_public___attribute__ ((visibility("default"))) int sd_event_dispatch(sd_event *e) {
3767 sd_event_source *p;
3768 int r;
3769
3770 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3770, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3771 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3771, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
3772 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3772, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
3773 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 3773, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
3774 assert_return(e->state == SD_EVENT_PENDING, -EBUSY)do { if (!(((__builtin_expect(!!(e->state == SD_EVENT_PENDING
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state == SD_EVENT_PENDING"), "../src/libsystemd/sd-event/sd-event.c"
, 3774, __PRETTY_FUNCTION__), 0))) return (-16); } while (0)
;
3775
3776 if (e->exit_requested)
3777 return dispatch_exit(e);
3778
3779 p = event_next_pending(e);
3780 if (p) {
3781 _unused___attribute__ ((unused)) _cleanup_(sd_event_unrefp)__attribute__((cleanup(sd_event_unrefp))) sd_event *ref = sd_event_ref(e);
3782
3783 e->state = SD_EVENT_RUNNING;
3784 r = source_dispatch(p);
3785 e->state = SD_EVENT_INITIAL;
3786 return r;
3787 }
3788
3789 e->state = SD_EVENT_INITIAL;
3790
3791 return 1;
3792}
3793
3794static void event_log_delays(sd_event *e) {
3795 char b[ELEMENTSOF(e->delays)__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(e->delays), typeof(&*(e->delays))), sizeof(
e->delays)/sizeof((e->delays)[0]), ((void)0)))
* DECIMAL_STR_MAX(unsigned)(2+(sizeof(unsigned) <= 1 ? 3 : sizeof(unsigned) <= 2 ?
5 : sizeof(unsigned) <= 4 ? 10 : sizeof(unsigned) <= 8
? 20 : sizeof(int[-2*(sizeof(unsigned) > 8)])))
+ 1];
3796 unsigned i;
3797 int o;
3798
3799 for (i = o = 0; i < ELEMENTSOF(e->delays)__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(e->delays), typeof(&*(e->delays))), sizeof(
e->delays)/sizeof((e->delays)[0]), ((void)0)))
; i++) {
3800 o += snprintf(&b[o], sizeof(b) - o, "%u ", e->delays[i]);
3801 e->delays[i] = 0;
3802 }
3803 log_debug("Event loop iterations: %.*s", o, b)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/libsystemd/sd-event/sd-event.c", 3803, __func__, "Event loop iterations: %.*s"
, o, b) : -abs(_e); })
;
3804}
3805
3806_public___attribute__ ((visibility("default"))) int sd_event_run(sd_event *e, uint64_t timeout) {
3807 int r;
3808
3809 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3809, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3810 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3810, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
3811 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3811, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
3812 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 3812, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
3813 assert_return(e->state == SD_EVENT_INITIAL, -EBUSY)do { if (!(((__builtin_expect(!!(e->state == SD_EVENT_INITIAL
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state == SD_EVENT_INITIAL"), "../src/libsystemd/sd-event/sd-event.c"
, 3813, __PRETTY_FUNCTION__), 0))) return (-16); } while (0)
;
3814
3815 if (e->profile_delays && e->last_run_usec != 0) {
3816 usec_t this_run;
3817 unsigned l;
3818
3819 this_run = now(CLOCK_MONOTONIC1);
3820
3821 l = u64log2(this_run - e->last_run_usec);
3822 assert(l < ELEMENTSOF(e->delays))do { if ((__builtin_expect(!!(!(l < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(e->delays), typeof(
&*(e->delays))), sizeof(e->delays)/sizeof((e->delays
)[0]), ((void)0))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("l < ELEMENTSOF(e->delays)"), "../src/libsystemd/sd-event/sd-event.c"
, 3822, __PRETTY_FUNCTION__); } while (0)
;
3823 e->delays[l]++;
3824
3825 if (this_run - e->last_log_usec >= 5*USEC_PER_SEC((usec_t) 1000000ULL)) {
3826 event_log_delays(e);
3827 e->last_log_usec = this_run;
3828 }
3829 }
3830
3831 /* Make sure that none of the preparation callbacks ends up freeing the event source under our feet */
3832 _unused___attribute__ ((unused)) _cleanup_(sd_event_unrefp)__attribute__((cleanup(sd_event_unrefp))) sd_event *ref = sd_event_ref(e);
3833
3834 r = sd_event_prepare(e);
3835 if (r == 0)
3836 /* There was nothing? Then wait... */
3837 r = sd_event_wait(e, timeout);
3838
3839 if (e->profile_delays)
3840 e->last_run_usec = now(CLOCK_MONOTONIC1);
3841
3842 if (r > 0) {
3843 /* There's something now, then let's dispatch it */
3844 r = sd_event_dispatch(e);
3845 if (r < 0)
3846 return r;
3847
3848 return 1;
3849 }
3850
3851 return r;
3852}
3853
3854_public___attribute__ ((visibility("default"))) int sd_event_loop(sd_event *e) {
3855 int r;
3856
3857 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3857, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3858 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3858, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
3859 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3859, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
3860 assert_return(e->state == SD_EVENT_INITIAL, -EBUSY)do { if (!(((__builtin_expect(!!(e->state == SD_EVENT_INITIAL
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state == SD_EVENT_INITIAL"), "../src/libsystemd/sd-event/sd-event.c"
, 3860, __PRETTY_FUNCTION__), 0))) return (-16); } while (0)
;
3861
3862 _unused___attribute__ ((unused)) _cleanup_(sd_event_unrefp)__attribute__((cleanup(sd_event_unrefp))) sd_event *ref = NULL((void*)0);
3863
3864 while (e->state != SD_EVENT_FINISHED) {
3865 r = sd_event_run(e, (uint64_t) -1);
3866 if (r < 0)
3867 return r;
3868 }
3869
3870 return e->exit_code;
3871}
3872
3873_public___attribute__ ((visibility("default"))) int sd_event_get_fd(sd_event *e) {
3874
3875 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3875, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3876 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3876, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
3877 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3877, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
3878
3879 return e->epoll_fd;
3880}
3881
3882_public___attribute__ ((visibility("default"))) int sd_event_get_state(sd_event *e) {
3883 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3883, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3884 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3884, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
3885 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3885, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
3886
3887 return e->state;
3888}
3889
3890_public___attribute__ ((visibility("default"))) int sd_event_get_exit_code(sd_event *e, int *code) {
3891 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3891, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3892 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3892, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
3893 assert_return(code, -EINVAL)do { if (!(((__builtin_expect(!!(code),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("code"), "../src/libsystemd/sd-event/sd-event.c"
, 3893, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3894 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3894, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
3895
3896 if (!e->exit_requested)
3897 return -ENODATA61;
3898
3899 *code = e->exit_code;
3900 return 0;
3901}
3902
3903_public___attribute__ ((visibility("default"))) int sd_event_exit(sd_event *e, int code) {
3904 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3904, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3905 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3905, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
3906 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE)do { if (!(((__builtin_expect(!!(e->state != SD_EVENT_FINISHED
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("e->state != SD_EVENT_FINISHED"), "../src/libsystemd/sd-event/sd-event.c"
, 3906, __PRETTY_FUNCTION__), 0))) return (-116); } while (0)
;
3907 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3907, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
3908
3909 e->exit_requested = true1;
3910 e->exit_code = code;
3911
3912 return 0;
3913}
3914
3915_public___attribute__ ((visibility("default"))) int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) {
3916 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3916, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3917 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3917, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
3918 assert_return(usec, -EINVAL)do { if (!(((__builtin_expect(!!(usec),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("usec"), "../src/libsystemd/sd-event/sd-event.c"
, 3918, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3919 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3919, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
3920
3921 if (!TRIPLE_TIMESTAMP_HAS_CLOCK(clock)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){0, 8, 1, 7, 9})/sizeof(int)]; switch(clock
) { case 0: case 8: case 1: case 7: case 9: _found = 1; break
; default: break; } _found; })
)
3922 return -EOPNOTSUPP95;
3923
3924 /* Generate a clean error in case CLOCK_BOOTTIME is not available. Note that don't use clock_supported() here,
3925 * for a reason: there are systems where CLOCK_BOOTTIME is supported, but CLOCK_BOOTTIME_ALARM is not, but for
3926 * the purpose of getting the time this doesn't matter. */
3927 if (IN_SET(clock, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){7, 9})/sizeof(int)]; switch(clock) { case
7: case 9: _found = 1; break; default: break; } _found; })
&& !clock_boottime_supported())
3928 return -EOPNOTSUPP95;
3929
3930 if (!triple_timestamp_is_set(&e->timestamp)) {
3931 /* Implicitly fall back to now() if we never ran
3932 * before and thus have no cached time. */
3933 *usec = now(clock);
3934 return 1;
3935 }
3936
3937 *usec = triple_timestamp_by_clock(&e->timestamp, clock);
3938 return 0;
3939}
3940
3941_public___attribute__ ((visibility("default"))) int sd_event_default(sd_event **ret) {
3942 sd_event *e = NULL((void*)0);
3943 int r;
3944
3945 if (!ret)
3946 return !!default_event;
3947
3948 if (default_event) {
3949 *ret = sd_event_ref(default_event);
3950 return 0;
3951 }
3952
3953 r = sd_event_new(&e);
3954 if (r < 0)
3955 return r;
3956
3957 e->default_event_ptr = &default_event;
3958 e->tid = gettid();
3959 default_event = e;
3960
3961 *ret = e;
3962 return 1;
3963}
3964
3965_public___attribute__ ((visibility("default"))) int sd_event_get_tid(sd_event *e, pid_t *tid) {
3966 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3966, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3967 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3967, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
3968 assert_return(tid, -EINVAL)do { if (!(((__builtin_expect(!!(tid),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("tid"), "../src/libsystemd/sd-event/sd-event.c"
, 3968, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3969 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3969, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
3970
3971 if (e->tid != 0) {
3972 *tid = e->tid;
3973 return 0;
3974 }
3975
3976 return -ENXIO6;
3977}
3978
3979_public___attribute__ ((visibility("default"))) int sd_event_set_watchdog(sd_event *e, int b) {
3980 int r;
3981
3982 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 3982, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
3983 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3983, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
3984 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 3984, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
3985
3986 if (e->watchdog == !!b)
3987 return e->watchdog;
3988
3989 if (b) {
3990 struct epoll_event ev;
3991
3992 r = sd_watchdog_enabled(false0, &e->watchdog_period);
3993 if (r <= 0)
3994 return r;
3995
3996 /* Issue first ping immediately */
3997 sd_notify(false0, "WATCHDOG=1");
3998 e->watchdog_last = now(CLOCK_MONOTONIC1);
3999
4000 e->watchdog_fd = timerfd_create(CLOCK_MONOTONIC1, TFD_NONBLOCKTFD_NONBLOCK|TFD_CLOEXECTFD_CLOEXEC);
4001 if (e->watchdog_fd < 0)
4002 return -errno(*__errno_location ());
4003
4004 r = arm_watchdog(e);
4005 if (r < 0)
4006 goto fail;
4007
4008 ev = (struct epoll_event) {
4009 .events = EPOLLINEPOLLIN,
4010 .data.ptr = INT_TO_PTR(SOURCE_WATCHDOG)((void *) ((intptr_t) (SOURCE_WATCHDOG))),
4011 };
4012
4013 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD1, e->watchdog_fd, &ev);
4014 if (r < 0) {
4015 r = -errno(*__errno_location ());
4016 goto fail;
4017 }
4018
4019 } else {
4020 if (e->watchdog_fd >= 0) {
4021 epoll_ctl(e->epoll_fd, EPOLL_CTL_DEL2, e->watchdog_fd, NULL((void*)0));
4022 e->watchdog_fd = safe_close(e->watchdog_fd);
4023 }
4024 }
4025
4026 e->watchdog = !!b;
4027 return e->watchdog;
4028
4029fail:
4030 e->watchdog_fd = safe_close(e->watchdog_fd);
4031 return r;
4032}
4033
4034_public___attribute__ ((visibility("default"))) int sd_event_get_watchdog(sd_event *e) {
4035 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 4035, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
4036 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 4036, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
4037 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 4037, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
4038
4039 return e->watchdog;
4040}
4041
4042_public___attribute__ ((visibility("default"))) int sd_event_get_iteration(sd_event *e, uint64_t *ret) {
4043 assert_return(e, -EINVAL)do { if (!(((__builtin_expect(!!(e),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("e"), "../src/libsystemd/sd-event/sd-event.c"
, 4043, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
4044 assert_return(e = event_resolve(e), -ENOPKG)do { if (!(((__builtin_expect(!!(e = event_resolve(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("e = event_resolve(e)"
), "../src/libsystemd/sd-event/sd-event.c", 4044, __PRETTY_FUNCTION__
), 0))) return (-65); } while (0)
;
4045 assert_return(!event_pid_changed(e), -ECHILD)do { if (!(((__builtin_expect(!!(!event_pid_changed(e)),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("!event_pid_changed(e)"
), "../src/libsystemd/sd-event/sd-event.c", 4045, __PRETTY_FUNCTION__
), 0))) return (-10); } while (0)
;
4046
4047 *ret = e->iteration;
4048 return 0;
4049}
4050
4051_public___attribute__ ((visibility("default"))) int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback) {
4052 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 4052, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
4053
4054 s->destroy_callback = callback;
4055 return 0;
4056}
4057
4058_public___attribute__ ((visibility("default"))) int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t *ret) {
4059 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 4059, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
4060
4061 if (ret)
4062 *ret = s->destroy_callback;
4063
4064 return !!s->destroy_callback;
4065}
4066
4067_public___attribute__ ((visibility("default"))) int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval, unsigned burst) {
4068 int r;
4069
4070 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 4070, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
4071
4072 /* Turning on ratelimiting on event source types that don't support it, is a loggable offense. Doing
4073 * so is a programming error. */
4074 assert_return(EVENT_SOURCE_CAN_RATE_LIMIT(s->type), -EDOM)do { if (!(((__builtin_expect(!!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((s->type)) { case SOURCE_IO: case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
case SOURCE_SIGNAL: case SOURCE_DEFER: case SOURCE_INOTIFY: _found
= 1; break; default: break; } _found; })),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("EVENT_SOURCE_CAN_RATE_LIMIT(s->type)"
), "../src/libsystemd/sd-event/sd-event.c", 4074, __PRETTY_FUNCTION__
), 0))) return (-33); } while (0)
;
4075
4076 /* When ratelimiting is configured we'll always reset the rate limit state first and start fresh,
4077 * non-ratelimited. */
4078 r = event_source_leave_ratelimit(s);
4079 if (r < 0)
4080 return r;
4081
4082 RATELIMIT_INIT(s->rate_limit, interval, burst)do { RateLimit *_r = &(s->rate_limit); _r->interval
= (interval); _r->burst = (burst); _r->num = 0; _r->
begin = 0; } while (0)
;
4083 return 0;
4084}
4085
4086_public___attribute__ ((visibility("default"))) int sd_event_source_get_ratelimit(sd_event_source *s, uint64_t *ret_interval, unsigned *ret_burst) {
4087 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 4087, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
4088
4089 /* Querying whether an event source has ratelimiting configured is not a loggable offsense, hence
4090 * don't use assert_return(). Unlike turning on ratelimiting it's not really a programming error */
4091 if (!EVENT_SOURCE_CAN_RATE_LIMIT(s->type)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((s->type)) { case SOURCE_IO: case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
case SOURCE_SIGNAL: case SOURCE_DEFER: case SOURCE_INOTIFY: _found
= 1; break; default: break; } _found; })
)
4092 return -EDOM33;
4093
4094 if (!ratelimit_configured(&s->rate_limit))
4095 return -ENOEXEC8;
4096
4097 if (ret_interval)
4098 *ret_interval = s->rate_limit.interval;
4099 if (ret_burst)
4100 *ret_burst = s->rate_limit.burst;
4101
4102 return 0;
4103}
4104
4105_public___attribute__ ((visibility("default"))) int sd_event_source_is_ratelimited(sd_event_source *s) {
4106 assert_return(s, -EINVAL)do { if (!(((__builtin_expect(!!(s),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/libsystemd/sd-event/sd-event.c"
, 4106, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
4107
4108 if (!EVENT_SOURCE_CAN_RATE_LIMIT(s->type)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOURCE_IO, SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME
, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM
, SOURCE_SIGNAL, SOURCE_DEFER, SOURCE_INOTIFY})/sizeof(int)];
switch((s->type)) { case SOURCE_IO: case SOURCE_TIME_REALTIME
: case SOURCE_TIME_BOOTTIME: case SOURCE_TIME_MONOTONIC: case
SOURCE_TIME_REALTIME_ALARM: case SOURCE_TIME_BOOTTIME_ALARM:
case SOURCE_SIGNAL: case SOURCE_DEFER: case SOURCE_INOTIFY: _found
= 1; break; default: break; } _found; })
)
4109 return false0;
4110
4111 if (!ratelimit_configured(&s->rate_limit))
4112 return false0;
4113
4114 return s->ratelimited;
4115}