]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-event/sd-event.c
Merge pull request #7388 from keszybz/doc-tweak
[thirdparty/systemd.git] / src / libsystemd / sd-event / sd-event.c
CommitLineData
fd38203a
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2013 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
20#include <sys/epoll.h>
21#include <sys/timerfd.h>
22#include <sys/wait.h>
23
cde93897 24#include "sd-daemon.h"
07630cea
LP
25#include "sd-event.h"
26#include "sd-id128.h"
27
b5efdb8a 28#include "alloc-util.h"
3ffd4af2 29#include "fd-util.h"
fd38203a 30#include "hashmap.h"
07630cea
LP
31#include "list.h"
32#include "macro.h"
afc6adb5 33#include "missing.h"
07630cea 34#include "prioq.h"
4a0b58c4 35#include "process-util.h"
6e9feda3 36#include "set.h"
24882e06 37#include "signal-util.h"
55cbfaa5 38#include "string-table.h"
07630cea
LP
39#include "string-util.h"
40#include "time-util.h"
41#include "util.h"
fd38203a 42
c2ba3ad6 43#define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC)
fd38203a
LP
44
45typedef enum EventSourceType {
46 SOURCE_IO,
6a0f1f6d 47 SOURCE_TIME_REALTIME,
a8548816 48 SOURCE_TIME_BOOTTIME,
6a0f1f6d
LP
49 SOURCE_TIME_MONOTONIC,
50 SOURCE_TIME_REALTIME_ALARM,
51 SOURCE_TIME_BOOTTIME_ALARM,
fd38203a
LP
52 SOURCE_SIGNAL,
53 SOURCE_CHILD,
da7e457c 54 SOURCE_DEFER,
6e9feda3 55 SOURCE_POST,
6203e07a 56 SOURCE_EXIT,
6a0f1f6d 57 SOURCE_WATCHDOG,
a71fe8b8 58 _SOURCE_EVENT_SOURCE_TYPE_MAX,
6a0f1f6d 59 _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1
fd38203a
LP
60} EventSourceType;
61
55cbfaa5
DM
62static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] = {
63 [SOURCE_IO] = "io",
64 [SOURCE_TIME_REALTIME] = "realtime",
65 [SOURCE_TIME_BOOTTIME] = "bootime",
66 [SOURCE_TIME_MONOTONIC] = "monotonic",
67 [SOURCE_TIME_REALTIME_ALARM] = "realtime-alarm",
68 [SOURCE_TIME_BOOTTIME_ALARM] = "boottime-alarm",
69 [SOURCE_SIGNAL] = "signal",
70 [SOURCE_CHILD] = "child",
71 [SOURCE_DEFER] = "defer",
72 [SOURCE_POST] = "post",
73 [SOURCE_EXIT] = "exit",
74 [SOURCE_WATCHDOG] = "watchdog",
75};
76
77DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(event_source_type, int);
78
9da4cb2b
LP
79/* All objects we use in epoll events start with this value, so that
80 * we know how to dispatch it */
81typedef enum WakeupType {
82 WAKEUP_NONE,
83 WAKEUP_EVENT_SOURCE,
84 WAKEUP_CLOCK_DATA,
85 WAKEUP_SIGNAL_DATA,
86 _WAKEUP_TYPE_MAX,
87 _WAKEUP_TYPE_INVALID = -1,
88} WakeupType;
89
a8548816 90#define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM)
6a0f1f6d 91
fd38203a 92struct sd_event_source {
9da4cb2b
LP
93 WakeupType wakeup;
94
da7e457c 95 unsigned n_ref;
fd38203a
LP
96
97 sd_event *event;
98 void *userdata;
718db961 99 sd_event_handler_t prepare;
fd38203a 100
356779df 101 char *description;
f7f53e9e 102
6a0f1f6d 103 EventSourceType type:5;
baf76283 104 int enabled:3;
fd38203a 105 bool pending:1;
12179984 106 bool dispatching:1;
a71fe8b8 107 bool floating:1;
fd38203a 108
31927c16 109 int64_t priority;
fd38203a
LP
110 unsigned pending_index;
111 unsigned prepare_index;
60a3b1e1
LP
112 uint64_t pending_iteration;
113 uint64_t prepare_iteration;
fd38203a 114
a71fe8b8
LP
115 LIST_FIELDS(sd_event_source, sources);
116
fd38203a
LP
117 union {
118 struct {
718db961 119 sd_event_io_handler_t callback;
fd38203a
LP
120 int fd;
121 uint32_t events;
122 uint32_t revents;
123 bool registered:1;
124 } io;
125 struct {
718db961 126 sd_event_time_handler_t callback;
c2ba3ad6
LP
127 usec_t next, accuracy;
128 unsigned earliest_index;
129 unsigned latest_index;
fd38203a
LP
130 } time;
131 struct {
718db961 132 sd_event_signal_handler_t callback;
fd38203a
LP
133 struct signalfd_siginfo siginfo;
134 int sig;
135 } signal;
136 struct {
718db961 137 sd_event_child_handler_t callback;
fd38203a
LP
138 siginfo_t siginfo;
139 pid_t pid;
140 int options;
141 } child;
142 struct {
718db961 143 sd_event_handler_t callback;
fd38203a 144 } defer;
6e9feda3
LP
145 struct {
146 sd_event_handler_t callback;
147 } post;
da7e457c 148 struct {
718db961 149 sd_event_handler_t callback;
da7e457c 150 unsigned prioq_index;
6203e07a 151 } exit;
fd38203a
LP
152 };
153};
154
6a0f1f6d 155struct clock_data {
9da4cb2b 156 WakeupType wakeup;
6a0f1f6d
LP
157 int fd;
158
159 /* For all clocks we maintain two priority queues each, one
160 * ordered for the earliest times the events may be
161 * dispatched, and one ordered by the latest times they must
162 * have been dispatched. The range between the top entries in
163 * the two prioqs is the time window we can freely schedule
164 * wakeups in */
165
166 Prioq *earliest;
167 Prioq *latest;
168 usec_t next;
212bbb17
TG
169
170 bool needs_rearm:1;
6a0f1f6d
LP
171};
172
9da4cb2b
LP
173struct signal_data {
174 WakeupType wakeup;
175
176 /* For each priority we maintain one signal fd, so that we
177 * only have to dequeue a single event per priority at a
178 * time. */
179
180 int fd;
181 int64_t priority;
182 sigset_t sigset;
183 sd_event_source *current;
184};
185
fd38203a 186struct sd_event {
da7e457c 187 unsigned n_ref;
fd38203a
LP
188
189 int epoll_fd;
cde93897 190 int watchdog_fd;
fd38203a
LP
191
192 Prioq *pending;
193 Prioq *prepare;
c2ba3ad6 194
a8548816 195 /* timerfd_create() only supports these five clocks so far. We
6a0f1f6d
LP
196 * can add support for more clocks when the kernel learns to
197 * deal with them, too. */
198 struct clock_data realtime;
a8548816 199 struct clock_data boottime;
6a0f1f6d
LP
200 struct clock_data monotonic;
201 struct clock_data realtime_alarm;
202 struct clock_data boottime_alarm;
fd38203a 203
da7e457c
LP
204 usec_t perturb;
205
9da4cb2b
LP
206 sd_event_source **signal_sources; /* indexed by signal number */
207 Hashmap *signal_data; /* indexed by priority */
fd38203a
LP
208
209 Hashmap *child_sources;
baf76283 210 unsigned n_enabled_child_sources;
fd38203a 211
6e9feda3
LP
212 Set *post_sources;
213
6203e07a 214 Prioq *exit;
fd38203a 215
da7e457c 216 pid_t original_pid;
c2ba3ad6 217
60a3b1e1 218 uint64_t iteration;
e475d10c 219 triple_timestamp timestamp;
da7e457c 220 int state;
eaa3cbef 221
6203e07a 222 bool exit_requested:1;
da7e457c 223 bool need_process_child:1;
cde93897 224 bool watchdog:1;
34b87517 225 bool profile_delays:1;
afc6adb5 226
6203e07a
LP
227 int exit_code;
228
afc6adb5
LP
229 pid_t tid;
230 sd_event **default_event_ptr;
cde93897
LP
231
232 usec_t watchdog_last, watchdog_period;
15b38f93
LP
233
234 unsigned n_sources;
a71fe8b8
LP
235
236 LIST_HEAD(sd_event_source, sources);
34b87517
VC
237
238 usec_t last_run, last_log;
239 unsigned delays[sizeof(usec_t) * 8];
fd38203a
LP
240};
241
a71fe8b8
LP
242static void source_disconnect(sd_event_source *s);
243
fd38203a
LP
244static int pending_prioq_compare(const void *a, const void *b) {
245 const sd_event_source *x = a, *y = b;
246
247 assert(x->pending);
248 assert(y->pending);
249
baf76283
LP
250 /* Enabled ones first */
251 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
fd38203a 252 return -1;
baf76283 253 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
fd38203a
LP
254 return 1;
255
256 /* Lower priority values first */
257 if (x->priority < y->priority)
258 return -1;
259 if (x->priority > y->priority)
260 return 1;
261
262 /* Older entries first */
263 if (x->pending_iteration < y->pending_iteration)
264 return -1;
265 if (x->pending_iteration > y->pending_iteration)
266 return 1;
267
fd38203a
LP
268 return 0;
269}
270
271static int prepare_prioq_compare(const void *a, const void *b) {
272 const sd_event_source *x = a, *y = b;
273
274 assert(x->prepare);
275 assert(y->prepare);
276
8046c457
KK
277 /* Enabled ones first */
278 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
279 return -1;
280 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
281 return 1;
282
fd38203a
LP
283 /* Move most recently prepared ones last, so that we can stop
284 * preparing as soon as we hit one that has already been
285 * prepared in the current iteration */
286 if (x->prepare_iteration < y->prepare_iteration)
287 return -1;
288 if (x->prepare_iteration > y->prepare_iteration)
289 return 1;
290
fd38203a
LP
291 /* Lower priority values first */
292 if (x->priority < y->priority)
293 return -1;
294 if (x->priority > y->priority)
295 return 1;
296
fd38203a
LP
297 return 0;
298}
299
c2ba3ad6 300static int earliest_time_prioq_compare(const void *a, const void *b) {
fd38203a
LP
301 const sd_event_source *x = a, *y = b;
302
6a0f1f6d
LP
303 assert(EVENT_SOURCE_IS_TIME(x->type));
304 assert(x->type == y->type);
fd38203a 305
baf76283
LP
306 /* Enabled ones first */
307 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
fd38203a 308 return -1;
baf76283 309 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
fd38203a
LP
310 return 1;
311
312 /* Move the pending ones to the end */
313 if (!x->pending && y->pending)
314 return -1;
315 if (x->pending && !y->pending)
316 return 1;
317
318 /* Order by time */
319 if (x->time.next < y->time.next)
320 return -1;
321 if (x->time.next > y->time.next)
a99badf5 322 return 1;
fd38203a 323
fd38203a
LP
324 return 0;
325}
326
1bce0ffa
LP
327static usec_t time_event_source_latest(const sd_event_source *s) {
328 return usec_add(s->time.next, s->time.accuracy);
329}
330
c2ba3ad6
LP
331static int latest_time_prioq_compare(const void *a, const void *b) {
332 const sd_event_source *x = a, *y = b;
333
6a0f1f6d
LP
334 assert(EVENT_SOURCE_IS_TIME(x->type));
335 assert(x->type == y->type);
c2ba3ad6 336
baf76283
LP
337 /* Enabled ones first */
338 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
c2ba3ad6 339 return -1;
baf76283 340 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
c2ba3ad6
LP
341 return 1;
342
343 /* Move the pending ones to the end */
344 if (!x->pending && y->pending)
345 return -1;
346 if (x->pending && !y->pending)
347 return 1;
348
349 /* Order by time */
1bce0ffa 350 if (time_event_source_latest(x) < time_event_source_latest(y))
c2ba3ad6 351 return -1;
1bce0ffa 352 if (time_event_source_latest(x) > time_event_source_latest(y))
a99badf5 353 return 1;
c2ba3ad6 354
c2ba3ad6
LP
355 return 0;
356}
357
6203e07a 358static int exit_prioq_compare(const void *a, const void *b) {
da7e457c
LP
359 const sd_event_source *x = a, *y = b;
360
6203e07a
LP
361 assert(x->type == SOURCE_EXIT);
362 assert(y->type == SOURCE_EXIT);
da7e457c 363
baf76283
LP
364 /* Enabled ones first */
365 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
da7e457c 366 return -1;
baf76283 367 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
da7e457c
LP
368 return 1;
369
370 /* Lower priority values first */
371 if (x->priority < y->priority)
372 return -1;
373 if (x->priority > y->priority)
374 return 1;
375
da7e457c
LP
376 return 0;
377}
378
6a0f1f6d
LP
379static void free_clock_data(struct clock_data *d) {
380 assert(d);
9da4cb2b 381 assert(d->wakeup == WAKEUP_CLOCK_DATA);
6a0f1f6d
LP
382
383 safe_close(d->fd);
384 prioq_free(d->earliest);
385 prioq_free(d->latest);
386}
387
fd38203a 388static void event_free(sd_event *e) {
a71fe8b8
LP
389 sd_event_source *s;
390
fd38203a 391 assert(e);
a71fe8b8
LP
392
393 while ((s = e->sources)) {
394 assert(s->floating);
395 source_disconnect(s);
396 sd_event_source_unref(s);
397 }
398
15b38f93 399 assert(e->n_sources == 0);
fd38203a 400
afc6adb5
LP
401 if (e->default_event_ptr)
402 *(e->default_event_ptr) = NULL;
403
03e334a1 404 safe_close(e->epoll_fd);
03e334a1 405 safe_close(e->watchdog_fd);
cde93897 406
6a0f1f6d 407 free_clock_data(&e->realtime);
a8548816 408 free_clock_data(&e->boottime);
6a0f1f6d
LP
409 free_clock_data(&e->monotonic);
410 free_clock_data(&e->realtime_alarm);
411 free_clock_data(&e->boottime_alarm);
412
fd38203a
LP
413 prioq_free(e->pending);
414 prioq_free(e->prepare);
6203e07a 415 prioq_free(e->exit);
fd38203a
LP
416
417 free(e->signal_sources);
9da4cb2b 418 hashmap_free(e->signal_data);
fd38203a
LP
419
420 hashmap_free(e->child_sources);
6e9feda3 421 set_free(e->post_sources);
fd38203a
LP
422 free(e);
423}
424
f7262a9f 425_public_ int sd_event_new(sd_event** ret) {
fd38203a
LP
426 sd_event *e;
427 int r;
428
305f78bf 429 assert_return(ret, -EINVAL);
fd38203a
LP
430
431 e = new0(sd_event, 1);
432 if (!e)
433 return -ENOMEM;
434
da7e457c 435 e->n_ref = 1;
9da4cb2b 436 e->watchdog_fd = e->epoll_fd = e->realtime.fd = e->boottime.fd = e->monotonic.fd = e->realtime_alarm.fd = e->boottime_alarm.fd = -1;
3a43da28 437 e->realtime.next = e->boottime.next = e->monotonic.next = e->realtime_alarm.next = e->boottime_alarm.next = USEC_INFINITY;
9da4cb2b 438 e->realtime.wakeup = e->boottime.wakeup = e->monotonic.wakeup = e->realtime_alarm.wakeup = e->boottime_alarm.wakeup = WAKEUP_CLOCK_DATA;
df0ff127 439 e->original_pid = getpid_cached();
3a43da28 440 e->perturb = USEC_INFINITY;
fd38203a 441
c983e776
EV
442 r = prioq_ensure_allocated(&e->pending, pending_prioq_compare);
443 if (r < 0)
fd38203a 444 goto fail;
fd38203a
LP
445
446 e->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
447 if (e->epoll_fd < 0) {
448 r = -errno;
449 goto fail;
450 }
451
34b87517 452 if (secure_getenv("SD_EVENT_PROFILE_DELAYS")) {
34a6843d 453 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.");
34b87517
VC
454 e->profile_delays = true;
455 }
456
fd38203a
LP
457 *ret = e;
458 return 0;
459
460fail:
461 event_free(e);
462 return r;
463}
464
f7262a9f 465_public_ sd_event* sd_event_ref(sd_event *e) {
6680dd6b
LP
466
467 if (!e)
468 return NULL;
fd38203a 469
da7e457c
LP
470 assert(e->n_ref >= 1);
471 e->n_ref++;
fd38203a
LP
472
473 return e;
474}
475
f7262a9f 476_public_ sd_event* sd_event_unref(sd_event *e) {
5b1bc83f
LP
477
478 if (!e)
479 return NULL;
fd38203a 480
da7e457c
LP
481 assert(e->n_ref >= 1);
482 e->n_ref--;
483
484 if (e->n_ref <= 0)
fd38203a
LP
485 event_free(e);
486
487 return NULL;
488}
489
eaa3cbef
LP
490static bool event_pid_changed(sd_event *e) {
491 assert(e);
492
a2360a46 493 /* We don't support people creating an event loop and keeping
eaa3cbef
LP
494 * it around over a fork(). Let's complain. */
495
df0ff127 496 return e->original_pid != getpid_cached();
eaa3cbef
LP
497}
498
366e6411 499static void source_io_unregister(sd_event_source *s) {
fd38203a
LP
500 int r;
501
502 assert(s);
503 assert(s->type == SOURCE_IO);
504
f6806734 505 if (event_pid_changed(s->event))
366e6411 506 return;
f6806734 507
fd38203a 508 if (!s->io.registered)
366e6411 509 return;
fd38203a
LP
510
511 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, s->io.fd, NULL);
556c25cf 512 if (r < 0)
55cbfaa5
DM
513 log_debug_errno(errno, "Failed to remove source %s (type %s) from epoll: %m",
514 strna(s->description), event_source_type_to_string(s->type));
fd38203a
LP
515
516 s->io.registered = false;
fd38203a
LP
517}
518
305f78bf
LP
519static int source_io_register(
520 sd_event_source *s,
521 int enabled,
522 uint32_t events) {
523
fd38203a
LP
524 struct epoll_event ev = {};
525 int r;
526
527 assert(s);
528 assert(s->type == SOURCE_IO);
baf76283 529 assert(enabled != SD_EVENT_OFF);
fd38203a
LP
530
531 ev.events = events;
532 ev.data.ptr = s;
533
baf76283 534 if (enabled == SD_EVENT_ONESHOT)
fd38203a
LP
535 ev.events |= EPOLLONESHOT;
536
537 if (s->io.registered)
538 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_MOD, s->io.fd, &ev);
539 else
540 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_ADD, s->io.fd, &ev);
fd38203a
LP
541 if (r < 0)
542 return -errno;
543
544 s->io.registered = true;
545
546 return 0;
547}
548
6a0f1f6d
LP
549static clockid_t event_source_type_to_clock(EventSourceType t) {
550
551 switch (t) {
552
553 case SOURCE_TIME_REALTIME:
554 return CLOCK_REALTIME;
555
a8548816
TG
556 case SOURCE_TIME_BOOTTIME:
557 return CLOCK_BOOTTIME;
558
6a0f1f6d
LP
559 case SOURCE_TIME_MONOTONIC:
560 return CLOCK_MONOTONIC;
561
562 case SOURCE_TIME_REALTIME_ALARM:
563 return CLOCK_REALTIME_ALARM;
564
565 case SOURCE_TIME_BOOTTIME_ALARM:
566 return CLOCK_BOOTTIME_ALARM;
567
568 default:
569 return (clockid_t) -1;
570 }
571}
572
573static EventSourceType clock_to_event_source_type(clockid_t clock) {
574
575 switch (clock) {
576
577 case CLOCK_REALTIME:
578 return SOURCE_TIME_REALTIME;
579
a8548816
TG
580 case CLOCK_BOOTTIME:
581 return SOURCE_TIME_BOOTTIME;
582
6a0f1f6d
LP
583 case CLOCK_MONOTONIC:
584 return SOURCE_TIME_MONOTONIC;
585
586 case CLOCK_REALTIME_ALARM:
587 return SOURCE_TIME_REALTIME_ALARM;
588
589 case CLOCK_BOOTTIME_ALARM:
590 return SOURCE_TIME_BOOTTIME_ALARM;
591
592 default:
593 return _SOURCE_EVENT_SOURCE_TYPE_INVALID;
594 }
595}
596
597static struct clock_data* event_get_clock_data(sd_event *e, EventSourceType t) {
598 assert(e);
599
600 switch (t) {
601
602 case SOURCE_TIME_REALTIME:
603 return &e->realtime;
604
a8548816
TG
605 case SOURCE_TIME_BOOTTIME:
606 return &e->boottime;
607
6a0f1f6d
LP
608 case SOURCE_TIME_MONOTONIC:
609 return &e->monotonic;
610
611 case SOURCE_TIME_REALTIME_ALARM:
612 return &e->realtime_alarm;
613
614 case SOURCE_TIME_BOOTTIME_ALARM:
615 return &e->boottime_alarm;
616
617 default:
618 return NULL;
619 }
620}
621
9da4cb2b
LP
622static int event_make_signal_data(
623 sd_event *e,
624 int sig,
625 struct signal_data **ret) {
4807d2d0 626
f95387cd 627 struct epoll_event ev = {};
9da4cb2b
LP
628 struct signal_data *d;
629 bool added = false;
630 sigset_t ss_copy;
631 int64_t priority;
f95387cd
ZJS
632 int r;
633
634 assert(e);
635
f6806734 636 if (event_pid_changed(e))
9da4cb2b 637 return -ECHILD;
f6806734 638
9da4cb2b
LP
639 if (e->signal_sources && e->signal_sources[sig])
640 priority = e->signal_sources[sig]->priority;
641 else
642 priority = 0;
f95387cd 643
9da4cb2b
LP
644 d = hashmap_get(e->signal_data, &priority);
645 if (d) {
646 if (sigismember(&d->sigset, sig) > 0) {
647 if (ret)
648 *ret = d;
649 return 0;
650 }
651 } else {
652 r = hashmap_ensure_allocated(&e->signal_data, &uint64_hash_ops);
653 if (r < 0)
654 return r;
655
656 d = new0(struct signal_data, 1);
657 if (!d)
658 return -ENOMEM;
659
660 d->wakeup = WAKEUP_SIGNAL_DATA;
661 d->fd = -1;
662 d->priority = priority;
663
664 r = hashmap_put(e->signal_data, &d->priority, d);
90f604d1
ZJS
665 if (r < 0) {
666 free(d);
9da4cb2b 667 return r;
90f604d1 668 }
f95387cd 669
9da4cb2b
LP
670 added = true;
671 }
672
673 ss_copy = d->sigset;
674 assert_se(sigaddset(&ss_copy, sig) >= 0);
675
676 r = signalfd(d->fd, &ss_copy, SFD_NONBLOCK|SFD_CLOEXEC);
677 if (r < 0) {
678 r = -errno;
679 goto fail;
680 }
681
682 d->sigset = ss_copy;
f95387cd 683
9da4cb2b
LP
684 if (d->fd >= 0) {
685 if (ret)
686 *ret = d;
f95387cd 687 return 0;
9da4cb2b
LP
688 }
689
690 d->fd = r;
f95387cd
ZJS
691
692 ev.events = EPOLLIN;
9da4cb2b 693 ev.data.ptr = d;
f95387cd 694
9da4cb2b
LP
695 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, d->fd, &ev);
696 if (r < 0) {
697 r = -errno;
698 goto fail;
f95387cd
ZJS
699 }
700
9da4cb2b
LP
701 if (ret)
702 *ret = d;
703
f95387cd 704 return 0;
9da4cb2b
LP
705
706fail:
707 if (added) {
708 d->fd = safe_close(d->fd);
709 hashmap_remove(e->signal_data, &d->priority);
710 free(d);
711 }
712
713 return r;
714}
715
716static void event_unmask_signal_data(sd_event *e, struct signal_data *d, int sig) {
717 assert(e);
718 assert(d);
719
720 /* Turns off the specified signal in the signal data
721 * object. If the signal mask of the object becomes empty that
722 * way removes it. */
723
724 if (sigismember(&d->sigset, sig) == 0)
725 return;
726
727 assert_se(sigdelset(&d->sigset, sig) >= 0);
728
729 if (sigisemptyset(&d->sigset)) {
730
731 /* If all the mask is all-zero we can get rid of the structure */
732 hashmap_remove(e->signal_data, &d->priority);
9da4cb2b
LP
733 safe_close(d->fd);
734 free(d);
735 return;
736 }
737
738 assert(d->fd >= 0);
739
740 if (signalfd(d->fd, &d->sigset, SFD_NONBLOCK|SFD_CLOEXEC) < 0)
741 log_debug_errno(errno, "Failed to unset signal bit, ignoring: %m");
742}
743
744static void event_gc_signal_data(sd_event *e, const int64_t *priority, int sig) {
745 struct signal_data *d;
746 static const int64_t zero_priority = 0;
747
748 assert(e);
749
750 /* Rechecks if the specified signal is still something we are
751 * interested in. If not, we'll unmask it, and possibly drop
752 * the signalfd for it. */
753
754 if (sig == SIGCHLD &&
755 e->n_enabled_child_sources > 0)
756 return;
757
758 if (e->signal_sources &&
759 e->signal_sources[sig] &&
760 e->signal_sources[sig]->enabled != SD_EVENT_OFF)
761 return;
762
763 /*
764 * The specified signal might be enabled in three different queues:
765 *
766 * 1) the one that belongs to the priority passed (if it is non-NULL)
767 * 2) the one that belongs to the priority of the event source of the signal (if there is one)
768 * 3) the 0 priority (to cover the SIGCHLD case)
769 *
770 * Hence, let's remove it from all three here.
771 */
772
773 if (priority) {
774 d = hashmap_get(e->signal_data, priority);
775 if (d)
776 event_unmask_signal_data(e, d, sig);
777 }
778
779 if (e->signal_sources && e->signal_sources[sig]) {
780 d = hashmap_get(e->signal_data, &e->signal_sources[sig]->priority);
781 if (d)
782 event_unmask_signal_data(e, d, sig);
783 }
784
785 d = hashmap_get(e->signal_data, &zero_priority);
786 if (d)
787 event_unmask_signal_data(e, d, sig);
f95387cd
ZJS
788}
789
a71fe8b8
LP
790static void source_disconnect(sd_event_source *s) {
791 sd_event *event;
792
fd38203a
LP
793 assert(s);
794
a71fe8b8
LP
795 if (!s->event)
796 return;
15b38f93 797
a71fe8b8 798 assert(s->event->n_sources > 0);
fd38203a 799
a71fe8b8 800 switch (s->type) {
fd38203a 801
a71fe8b8
LP
802 case SOURCE_IO:
803 if (s->io.fd >= 0)
804 source_io_unregister(s);
fd38203a 805
a71fe8b8 806 break;
6a0f1f6d 807
a71fe8b8 808 case SOURCE_TIME_REALTIME:
a8548816 809 case SOURCE_TIME_BOOTTIME:
a71fe8b8
LP
810 case SOURCE_TIME_MONOTONIC:
811 case SOURCE_TIME_REALTIME_ALARM:
812 case SOURCE_TIME_BOOTTIME_ALARM: {
813 struct clock_data *d;
fd38203a 814
a71fe8b8
LP
815 d = event_get_clock_data(s->event, s->type);
816 assert(d);
817
818 prioq_remove(d->earliest, s, &s->time.earliest_index);
819 prioq_remove(d->latest, s, &s->time.latest_index);
212bbb17 820 d->needs_rearm = true;
a71fe8b8
LP
821 break;
822 }
823
824 case SOURCE_SIGNAL:
825 if (s->signal.sig > 0) {
9da4cb2b 826
a71fe8b8
LP
827 if (s->event->signal_sources)
828 s->event->signal_sources[s->signal.sig] = NULL;
4807d2d0 829
9da4cb2b 830 event_gc_signal_data(s->event, &s->priority, s->signal.sig);
6a0f1f6d 831 }
fd38203a 832
a71fe8b8 833 break;
fd38203a 834
a71fe8b8
LP
835 case SOURCE_CHILD:
836 if (s->child.pid > 0) {
837 if (s->enabled != SD_EVENT_OFF) {
838 assert(s->event->n_enabled_child_sources > 0);
839 s->event->n_enabled_child_sources--;
4807d2d0 840 }
fd38203a 841
4a0b58c4 842 (void) hashmap_remove(s->event->child_sources, PID_TO_PTR(s->child.pid));
9da4cb2b 843 event_gc_signal_data(s->event, &s->priority, SIGCHLD);
a71fe8b8 844 }
fd38203a 845
a71fe8b8 846 break;
fd38203a 847
a71fe8b8
LP
848 case SOURCE_DEFER:
849 /* nothing */
850 break;
fd38203a 851
a71fe8b8
LP
852 case SOURCE_POST:
853 set_remove(s->event->post_sources, s);
854 break;
da7e457c 855
a71fe8b8
LP
856 case SOURCE_EXIT:
857 prioq_remove(s->event->exit, s, &s->exit.prioq_index);
858 break;
0eb2e0e3 859
a71fe8b8
LP
860 default:
861 assert_not_reached("Wut? I shouldn't exist.");
862 }
6e9feda3 863
a71fe8b8
LP
864 if (s->pending)
865 prioq_remove(s->event->pending, s, &s->pending_index);
9d3e3aa5 866
a71fe8b8
LP
867 if (s->prepare)
868 prioq_remove(s->event->prepare, s, &s->prepare_index);
fd38203a 869
a71fe8b8 870 event = s->event;
fd38203a 871
a71fe8b8
LP
872 s->type = _SOURCE_EVENT_SOURCE_TYPE_INVALID;
873 s->event = NULL;
874 LIST_REMOVE(sources, event->sources, s);
875 event->n_sources--;
fd38203a 876
a71fe8b8
LP
877 if (!s->floating)
878 sd_event_unref(event);
879}
880
881static void source_free(sd_event_source *s) {
882 assert(s);
fd38203a 883
a71fe8b8 884 source_disconnect(s);
356779df 885 free(s->description);
fd38203a
LP
886 free(s);
887}
888
889static int source_set_pending(sd_event_source *s, bool b) {
890 int r;
891
892 assert(s);
6203e07a 893 assert(s->type != SOURCE_EXIT);
fd38203a
LP
894
895 if (s->pending == b)
896 return 0;
897
898 s->pending = b;
899
900 if (b) {
901 s->pending_iteration = s->event->iteration;
902
903 r = prioq_put(s->event->pending, s, &s->pending_index);
904 if (r < 0) {
905 s->pending = false;
906 return r;
907 }
908 } else
909 assert_se(prioq_remove(s->event->pending, s, &s->pending_index));
910
6a0f1f6d
LP
911 if (EVENT_SOURCE_IS_TIME(s->type)) {
912 struct clock_data *d;
913
914 d = event_get_clock_data(s->event, s->type);
915 assert(d);
916
917 prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
918 prioq_reshuffle(d->latest, s, &s->time.latest_index);
212bbb17 919 d->needs_rearm = true;
2576a19e
LP
920 }
921
9da4cb2b
LP
922 if (s->type == SOURCE_SIGNAL && !b) {
923 struct signal_data *d;
924
925 d = hashmap_get(s->event->signal_data, &s->priority);
926 if (d && d->current == s)
927 d->current = NULL;
928 }
929
fd38203a
LP
930 return 0;
931}
932
a71fe8b8 933static sd_event_source *source_new(sd_event *e, bool floating, EventSourceType type) {
fd38203a
LP
934 sd_event_source *s;
935
936 assert(e);
937
938 s = new0(sd_event_source, 1);
939 if (!s)
940 return NULL;
941
da7e457c 942 s->n_ref = 1;
a71fe8b8 943 s->event = e;
4a134c49 944 s->floating = floating;
fd38203a 945 s->type = type;
fd38203a 946 s->pending_index = s->prepare_index = PRIOQ_IDX_NULL;
a71fe8b8
LP
947
948 if (!floating)
949 sd_event_ref(e);
fd38203a 950
a71fe8b8 951 LIST_PREPEND(sources, e->sources, s);
313cefa1 952 e->n_sources++;
15b38f93 953
fd38203a
LP
954 return s;
955}
956
f7262a9f 957_public_ int sd_event_add_io(
fd38203a 958 sd_event *e,
151b9b96 959 sd_event_source **ret,
fd38203a
LP
960 int fd,
961 uint32_t events,
718db961 962 sd_event_io_handler_t callback,
151b9b96 963 void *userdata) {
fd38203a
LP
964
965 sd_event_source *s;
966 int r;
967
305f78bf 968 assert_return(e, -EINVAL);
8ac43fee 969 assert_return(fd >= 0, -EBADF);
2a16a986 970 assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL);
305f78bf 971 assert_return(callback, -EINVAL);
da7e457c 972 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 973 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 974
a71fe8b8 975 s = source_new(e, !ret, SOURCE_IO);
fd38203a
LP
976 if (!s)
977 return -ENOMEM;
978
9da4cb2b 979 s->wakeup = WAKEUP_EVENT_SOURCE;
fd38203a
LP
980 s->io.fd = fd;
981 s->io.events = events;
982 s->io.callback = callback;
983 s->userdata = userdata;
baf76283 984 s->enabled = SD_EVENT_ON;
fd38203a 985
baf76283 986 r = source_io_register(s, s->enabled, events);
fd38203a
LP
987 if (r < 0) {
988 source_free(s);
050f74f2 989 return r;
fd38203a
LP
990 }
991
a71fe8b8
LP
992 if (ret)
993 *ret = s;
994
fd38203a
LP
995 return 0;
996}
997
52444dc4
LP
998static void initialize_perturb(sd_event *e) {
999 sd_id128_t bootid = {};
1000
1001 /* When we sleep for longer, we try to realign the wakeup to
1002 the same time wihtin each minute/second/250ms, so that
1003 events all across the system can be coalesced into a single
1004 CPU wakeup. However, let's take some system-specific
1005 randomness for this value, so that in a network of systems
1006 with synced clocks timer events are distributed a
1007 bit. Here, we calculate a perturbation usec offset from the
1008 boot ID. */
1009
3a43da28 1010 if (_likely_(e->perturb != USEC_INFINITY))
52444dc4
LP
1011 return;
1012
1013 if (sd_id128_get_boot(&bootid) >= 0)
1014 e->perturb = (bootid.qwords[0] ^ bootid.qwords[1]) % USEC_PER_MINUTE;
1015}
1016
fd38203a
LP
1017static int event_setup_timer_fd(
1018 sd_event *e,
6a0f1f6d
LP
1019 struct clock_data *d,
1020 clockid_t clock) {
fd38203a
LP
1021
1022 struct epoll_event ev = {};
1023 int r, fd;
1024
1025 assert(e);
6a0f1f6d 1026 assert(d);
fd38203a 1027
6a0f1f6d 1028 if (_likely_(d->fd >= 0))
fd38203a
LP
1029 return 0;
1030
6a0f1f6d 1031 fd = timerfd_create(clock, TFD_NONBLOCK|TFD_CLOEXEC);
fd38203a
LP
1032 if (fd < 0)
1033 return -errno;
1034
1035 ev.events = EPOLLIN;
9da4cb2b 1036 ev.data.ptr = d;
fd38203a
LP
1037
1038 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, fd, &ev);
1039 if (r < 0) {
03e334a1 1040 safe_close(fd);
fd38203a
LP
1041 return -errno;
1042 }
1043
6a0f1f6d 1044 d->fd = fd;
fd38203a
LP
1045 return 0;
1046}
1047
c4f1aff2
TG
1048static int time_exit_callback(sd_event_source *s, uint64_t usec, void *userdata) {
1049 assert(s);
1050
1051 return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata));
1052}
1053
6a0f1f6d 1054_public_ int sd_event_add_time(
fd38203a 1055 sd_event *e,
151b9b96 1056 sd_event_source **ret,
6a0f1f6d 1057 clockid_t clock,
fd38203a 1058 uint64_t usec,
c2ba3ad6 1059 uint64_t accuracy,
718db961 1060 sd_event_time_handler_t callback,
151b9b96 1061 void *userdata) {
fd38203a 1062
6a0f1f6d 1063 EventSourceType type;
fd38203a 1064 sd_event_source *s;
6a0f1f6d 1065 struct clock_data *d;
fd38203a
LP
1066 int r;
1067
305f78bf 1068 assert_return(e, -EINVAL);
305f78bf 1069 assert_return(accuracy != (uint64_t) -1, -EINVAL);
da7e457c 1070 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1071 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 1072
e475d10c
LP
1073 if (!clock_supported(clock)) /* Checks whether the kernel supports the clock */
1074 return -EOPNOTSUPP;
1075
1076 type = clock_to_event_source_type(clock); /* checks whether sd-event supports this clock */
1077 if (type < 0)
3411372e
LP
1078 return -EOPNOTSUPP;
1079
c4f1aff2
TG
1080 if (!callback)
1081 callback = time_exit_callback;
1082
6a0f1f6d
LP
1083 d = event_get_clock_data(e, type);
1084 assert(d);
c2ba3ad6 1085
c983e776
EV
1086 r = prioq_ensure_allocated(&d->earliest, earliest_time_prioq_compare);
1087 if (r < 0)
1088 return r;
fd38203a 1089
c983e776
EV
1090 r = prioq_ensure_allocated(&d->latest, latest_time_prioq_compare);
1091 if (r < 0)
1092 return r;
fd38203a 1093
6a0f1f6d
LP
1094 if (d->fd < 0) {
1095 r = event_setup_timer_fd(e, d, clock);
fd38203a
LP
1096 if (r < 0)
1097 return r;
1098 }
1099
a71fe8b8 1100 s = source_new(e, !ret, type);
fd38203a
LP
1101 if (!s)
1102 return -ENOMEM;
1103
1104 s->time.next = usec;
c2ba3ad6 1105 s->time.accuracy = accuracy == 0 ? DEFAULT_ACCURACY_USEC : accuracy;
fd38203a 1106 s->time.callback = callback;
da7e457c 1107 s->time.earliest_index = s->time.latest_index = PRIOQ_IDX_NULL;
fd38203a 1108 s->userdata = userdata;
baf76283 1109 s->enabled = SD_EVENT_ONESHOT;
fd38203a 1110
e07bbb7c
TG
1111 d->needs_rearm = true;
1112
6a0f1f6d 1113 r = prioq_put(d->earliest, s, &s->time.earliest_index);
c2ba3ad6
LP
1114 if (r < 0)
1115 goto fail;
1116
6a0f1f6d 1117 r = prioq_put(d->latest, s, &s->time.latest_index);
c2ba3ad6
LP
1118 if (r < 0)
1119 goto fail;
fd38203a 1120
a71fe8b8
LP
1121 if (ret)
1122 *ret = s;
1123
fd38203a 1124 return 0;
c2ba3ad6
LP
1125
1126fail:
1127 source_free(s);
1128 return r;
fd38203a
LP
1129}
1130
59bc1fd7
LP
1131static int signal_exit_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
1132 assert(s);
1133
1134 return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata));
1135}
1136
f7262a9f 1137_public_ int sd_event_add_signal(
305f78bf 1138 sd_event *e,
151b9b96 1139 sd_event_source **ret,
305f78bf 1140 int sig,
718db961 1141 sd_event_signal_handler_t callback,
151b9b96 1142 void *userdata) {
305f78bf 1143
fd38203a 1144 sd_event_source *s;
9da4cb2b 1145 struct signal_data *d;
3022d74b 1146 sigset_t ss;
fd38203a
LP
1147 int r;
1148
305f78bf 1149 assert_return(e, -EINVAL);
6eb7c172 1150 assert_return(SIGNAL_VALID(sig), -EINVAL);
da7e457c 1151 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1152 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 1153
59bc1fd7
LP
1154 if (!callback)
1155 callback = signal_exit_callback;
1156
3022d74b 1157 r = pthread_sigmask(SIG_SETMASK, NULL, &ss);
50e0d56c
LP
1158 if (r != 0)
1159 return -r;
3022d74b
LP
1160
1161 if (!sigismember(&ss, sig))
1162 return -EBUSY;
1163
fd38203a
LP
1164 if (!e->signal_sources) {
1165 e->signal_sources = new0(sd_event_source*, _NSIG);
1166 if (!e->signal_sources)
1167 return -ENOMEM;
1168 } else if (e->signal_sources[sig])
1169 return -EBUSY;
1170
a71fe8b8 1171 s = source_new(e, !ret, SOURCE_SIGNAL);
fd38203a
LP
1172 if (!s)
1173 return -ENOMEM;
1174
1175 s->signal.sig = sig;
1176 s->signal.callback = callback;
1177 s->userdata = userdata;
baf76283 1178 s->enabled = SD_EVENT_ON;
fd38203a
LP
1179
1180 e->signal_sources[sig] = s;
fd38203a 1181
9da4cb2b
LP
1182 r = event_make_signal_data(e, sig, &d);
1183 if (r < 0) {
1184 source_free(s);
1185 return r;
fd38203a
LP
1186 }
1187
f1f00dbb
LP
1188 /* Use the signal name as description for the event source by default */
1189 (void) sd_event_source_set_description(s, signal_to_string(sig));
1190
a71fe8b8
LP
1191 if (ret)
1192 *ret = s;
1193
fd38203a
LP
1194 return 0;
1195}
1196
f7262a9f 1197_public_ int sd_event_add_child(
305f78bf 1198 sd_event *e,
151b9b96 1199 sd_event_source **ret,
305f78bf
LP
1200 pid_t pid,
1201 int options,
718db961 1202 sd_event_child_handler_t callback,
151b9b96 1203 void *userdata) {
305f78bf 1204
fd38203a
LP
1205 sd_event_source *s;
1206 int r;
1207
305f78bf
LP
1208 assert_return(e, -EINVAL);
1209 assert_return(pid > 1, -EINVAL);
1210 assert_return(!(options & ~(WEXITED|WSTOPPED|WCONTINUED)), -EINVAL);
1211 assert_return(options != 0, -EINVAL);
1212 assert_return(callback, -EINVAL);
da7e457c 1213 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1214 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 1215
d5099efc 1216 r = hashmap_ensure_allocated(&e->child_sources, NULL);
fd38203a
LP
1217 if (r < 0)
1218 return r;
1219
4a0b58c4 1220 if (hashmap_contains(e->child_sources, PID_TO_PTR(pid)))
fd38203a
LP
1221 return -EBUSY;
1222
a71fe8b8 1223 s = source_new(e, !ret, SOURCE_CHILD);
fd38203a
LP
1224 if (!s)
1225 return -ENOMEM;
1226
1227 s->child.pid = pid;
1228 s->child.options = options;
1229 s->child.callback = callback;
1230 s->userdata = userdata;
baf76283 1231 s->enabled = SD_EVENT_ONESHOT;
fd38203a 1232
4a0b58c4 1233 r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s);
fd38203a
LP
1234 if (r < 0) {
1235 source_free(s);
1236 return r;
1237 }
1238
313cefa1 1239 e->n_enabled_child_sources++;
fd38203a 1240
9da4cb2b
LP
1241 r = event_make_signal_data(e, SIGCHLD, NULL);
1242 if (r < 0) {
1243 e->n_enabled_child_sources--;
1244 source_free(s);
1245 return r;
fd38203a
LP
1246 }
1247
c2ba3ad6
LP
1248 e->need_process_child = true;
1249
a71fe8b8
LP
1250 if (ret)
1251 *ret = s;
1252
fd38203a
LP
1253 return 0;
1254}
1255
f7262a9f 1256_public_ int sd_event_add_defer(
305f78bf 1257 sd_event *e,
151b9b96 1258 sd_event_source **ret,
718db961 1259 sd_event_handler_t callback,
151b9b96 1260 void *userdata) {
305f78bf 1261
fd38203a
LP
1262 sd_event_source *s;
1263 int r;
1264
305f78bf
LP
1265 assert_return(e, -EINVAL);
1266 assert_return(callback, -EINVAL);
da7e457c 1267 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1268 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 1269
a71fe8b8 1270 s = source_new(e, !ret, SOURCE_DEFER);
fd38203a
LP
1271 if (!s)
1272 return -ENOMEM;
1273
1274 s->defer.callback = callback;
1275 s->userdata = userdata;
baf76283 1276 s->enabled = SD_EVENT_ONESHOT;
fd38203a
LP
1277
1278 r = source_set_pending(s, true);
1279 if (r < 0) {
1280 source_free(s);
1281 return r;
1282 }
1283
a71fe8b8
LP
1284 if (ret)
1285 *ret = s;
1286
fd38203a
LP
1287 return 0;
1288}
1289
6e9feda3
LP
1290_public_ int sd_event_add_post(
1291 sd_event *e,
1292 sd_event_source **ret,
1293 sd_event_handler_t callback,
1294 void *userdata) {
1295
1296 sd_event_source *s;
1297 int r;
1298
1299 assert_return(e, -EINVAL);
1300 assert_return(callback, -EINVAL);
6e9feda3
LP
1301 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
1302 assert_return(!event_pid_changed(e), -ECHILD);
1303
d5099efc 1304 r = set_ensure_allocated(&e->post_sources, NULL);
6e9feda3
LP
1305 if (r < 0)
1306 return r;
1307
a71fe8b8 1308 s = source_new(e, !ret, SOURCE_POST);
6e9feda3
LP
1309 if (!s)
1310 return -ENOMEM;
1311
1312 s->post.callback = callback;
1313 s->userdata = userdata;
1314 s->enabled = SD_EVENT_ON;
1315
1316 r = set_put(e->post_sources, s);
1317 if (r < 0) {
1318 source_free(s);
1319 return r;
1320 }
1321
a71fe8b8
LP
1322 if (ret)
1323 *ret = s;
1324
6e9feda3
LP
1325 return 0;
1326}
1327
6203e07a 1328_public_ int sd_event_add_exit(
305f78bf 1329 sd_event *e,
151b9b96 1330 sd_event_source **ret,
718db961 1331 sd_event_handler_t callback,
151b9b96 1332 void *userdata) {
305f78bf 1333
da7e457c
LP
1334 sd_event_source *s;
1335 int r;
1336
1337 assert_return(e, -EINVAL);
1338 assert_return(callback, -EINVAL);
1339 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
1340 assert_return(!event_pid_changed(e), -ECHILD);
1341
c983e776
EV
1342 r = prioq_ensure_allocated(&e->exit, exit_prioq_compare);
1343 if (r < 0)
1344 return r;
da7e457c 1345
a71fe8b8 1346 s = source_new(e, !ret, SOURCE_EXIT);
fd38203a 1347 if (!s)
da7e457c 1348 return -ENOMEM;
fd38203a 1349
6203e07a 1350 s->exit.callback = callback;
da7e457c 1351 s->userdata = userdata;
6203e07a 1352 s->exit.prioq_index = PRIOQ_IDX_NULL;
baf76283 1353 s->enabled = SD_EVENT_ONESHOT;
da7e457c 1354
6203e07a 1355 r = prioq_put(s->event->exit, s, &s->exit.prioq_index);
da7e457c
LP
1356 if (r < 0) {
1357 source_free(s);
1358 return r;
1359 }
1360
a71fe8b8
LP
1361 if (ret)
1362 *ret = s;
1363
da7e457c
LP
1364 return 0;
1365}
1366
f7262a9f 1367_public_ sd_event_source* sd_event_source_ref(sd_event_source *s) {
6680dd6b
LP
1368
1369 if (!s)
1370 return NULL;
da7e457c
LP
1371
1372 assert(s->n_ref >= 1);
1373 s->n_ref++;
fd38203a
LP
1374
1375 return s;
1376}
1377
f7262a9f 1378_public_ sd_event_source* sd_event_source_unref(sd_event_source *s) {
5b1bc83f
LP
1379
1380 if (!s)
1381 return NULL;
fd38203a 1382
da7e457c
LP
1383 assert(s->n_ref >= 1);
1384 s->n_ref--;
1385
12179984
LP
1386 if (s->n_ref <= 0) {
1387 /* Here's a special hack: when we are called from a
1388 * dispatch handler we won't free the event source
1389 * immediately, but we will detach the fd from the
1390 * epoll. This way it is safe for the caller to unref
1391 * the event source and immediately close the fd, but
1392 * we still retain a valid event source object after
1393 * the callback. */
1394
1395 if (s->dispatching) {
1396 if (s->type == SOURCE_IO)
1397 source_io_unregister(s);
a71fe8b8
LP
1398
1399 source_disconnect(s);
12179984
LP
1400 } else
1401 source_free(s);
1402 }
fd38203a
LP
1403
1404 return NULL;
1405}
1406
356779df 1407_public_ int sd_event_source_set_description(sd_event_source *s, const char *description) {
f7f53e9e 1408 assert_return(s, -EINVAL);
f4b2933e 1409 assert_return(!event_pid_changed(s->event), -ECHILD);
f7f53e9e 1410
356779df 1411 return free_and_strdup(&s->description, description);
f7f53e9e
TG
1412}
1413
356779df 1414_public_ int sd_event_source_get_description(sd_event_source *s, const char **description) {
f7f53e9e 1415 assert_return(s, -EINVAL);
356779df 1416 assert_return(description, -EINVAL);
f4b2933e
LP
1417 assert_return(s->description, -ENXIO);
1418 assert_return(!event_pid_changed(s->event), -ECHILD);
f7f53e9e 1419
356779df 1420 *description = s->description;
f7f53e9e
TG
1421 return 0;
1422}
1423
adcc4ca3 1424_public_ sd_event *sd_event_source_get_event(sd_event_source *s) {
305f78bf 1425 assert_return(s, NULL);
eaa3cbef
LP
1426
1427 return s->event;
1428}
1429
f7262a9f 1430_public_ int sd_event_source_get_pending(sd_event_source *s) {
305f78bf 1431 assert_return(s, -EINVAL);
6203e07a 1432 assert_return(s->type != SOURCE_EXIT, -EDOM);
da7e457c 1433 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1434 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1435
1436 return s->pending;
1437}
1438
f7262a9f 1439_public_ int sd_event_source_get_io_fd(sd_event_source *s) {
305f78bf
LP
1440 assert_return(s, -EINVAL);
1441 assert_return(s->type == SOURCE_IO, -EDOM);
1442 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1443
1444 return s->io.fd;
1445}
1446
30caf8f3
LP
1447_public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) {
1448 int r;
1449
1450 assert_return(s, -EINVAL);
8ac43fee 1451 assert_return(fd >= 0, -EBADF);
30caf8f3
LP
1452 assert_return(s->type == SOURCE_IO, -EDOM);
1453 assert_return(!event_pid_changed(s->event), -ECHILD);
1454
1455 if (s->io.fd == fd)
1456 return 0;
1457
1458 if (s->enabled == SD_EVENT_OFF) {
1459 s->io.fd = fd;
1460 s->io.registered = false;
1461 } else {
1462 int saved_fd;
1463
1464 saved_fd = s->io.fd;
1465 assert(s->io.registered);
1466
1467 s->io.fd = fd;
1468 s->io.registered = false;
1469
1470 r = source_io_register(s, s->enabled, s->io.events);
1471 if (r < 0) {
1472 s->io.fd = saved_fd;
1473 s->io.registered = true;
1474 return r;
1475 }
1476
1477 epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, saved_fd, NULL);
1478 }
1479
1480 return 0;
1481}
1482
f7262a9f 1483_public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) {
305f78bf
LP
1484 assert_return(s, -EINVAL);
1485 assert_return(events, -EINVAL);
1486 assert_return(s->type == SOURCE_IO, -EDOM);
1487 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1488
1489 *events = s->io.events;
1490 return 0;
1491}
1492
f7262a9f 1493_public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) {
fd38203a
LP
1494 int r;
1495
305f78bf
LP
1496 assert_return(s, -EINVAL);
1497 assert_return(s->type == SOURCE_IO, -EDOM);
2a16a986 1498 assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL);
da7e457c 1499 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1500 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a 1501
b63c8d4f
DH
1502 /* edge-triggered updates are never skipped, so we can reset edges */
1503 if (s->io.events == events && !(events & EPOLLET))
fd38203a
LP
1504 return 0;
1505
baf76283 1506 if (s->enabled != SD_EVENT_OFF) {
e4715127 1507 r = source_io_register(s, s->enabled, events);
fd38203a
LP
1508 if (r < 0)
1509 return r;
1510 }
1511
1512 s->io.events = events;
503f39c3 1513 source_set_pending(s, false);
fd38203a
LP
1514
1515 return 0;
1516}
1517
f7262a9f 1518_public_ int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents) {
305f78bf
LP
1519 assert_return(s, -EINVAL);
1520 assert_return(revents, -EINVAL);
1521 assert_return(s->type == SOURCE_IO, -EDOM);
1522 assert_return(s->pending, -ENODATA);
1523 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1524
1525 *revents = s->io.revents;
1526 return 0;
1527}
1528
f7262a9f 1529_public_ int sd_event_source_get_signal(sd_event_source *s) {
305f78bf
LP
1530 assert_return(s, -EINVAL);
1531 assert_return(s->type == SOURCE_SIGNAL, -EDOM);
1532 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1533
1534 return s->signal.sig;
1535}
1536
31927c16 1537_public_ int sd_event_source_get_priority(sd_event_source *s, int64_t *priority) {
305f78bf
LP
1538 assert_return(s, -EINVAL);
1539 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a 1540
6680b8d1
ME
1541 *priority = s->priority;
1542 return 0;
fd38203a
LP
1543}
1544
31927c16 1545_public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) {
9da4cb2b
LP
1546 int r;
1547
305f78bf 1548 assert_return(s, -EINVAL);
da7e457c 1549 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1550 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1551
1552 if (s->priority == priority)
1553 return 0;
1554
9da4cb2b
LP
1555 if (s->type == SOURCE_SIGNAL && s->enabled != SD_EVENT_OFF) {
1556 struct signal_data *old, *d;
1557
1558 /* Move us from the signalfd belonging to the old
1559 * priority to the signalfd of the new priority */
1560
1561 assert_se(old = hashmap_get(s->event->signal_data, &s->priority));
1562
1563 s->priority = priority;
1564
1565 r = event_make_signal_data(s->event, s->signal.sig, &d);
1566 if (r < 0) {
1567 s->priority = old->priority;
1568 return r;
1569 }
1570
1571 event_unmask_signal_data(s->event, old, s->signal.sig);
1572 } else
1573 s->priority = priority;
fd38203a
LP
1574
1575 if (s->pending)
c2ba3ad6 1576 prioq_reshuffle(s->event->pending, s, &s->pending_index);
fd38203a
LP
1577
1578 if (s->prepare)
c2ba3ad6 1579 prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
fd38203a 1580
6203e07a
LP
1581 if (s->type == SOURCE_EXIT)
1582 prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
305f78bf 1583
fd38203a
LP
1584 return 0;
1585}
1586
f7262a9f 1587_public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) {
305f78bf
LP
1588 assert_return(s, -EINVAL);
1589 assert_return(m, -EINVAL);
1590 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a 1591
baf76283 1592 *m = s->enabled;
fd38203a
LP
1593 return 0;
1594}
1595
f7262a9f 1596_public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
fd38203a
LP
1597 int r;
1598
305f78bf 1599 assert_return(s, -EINVAL);
945c2931 1600 assert_return(IN_SET(m, SD_EVENT_OFF, SD_EVENT_ON, SD_EVENT_ONESHOT), -EINVAL);
305f78bf 1601 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a 1602
cc567911
LP
1603 /* If we are dead anyway, we are fine with turning off
1604 * sources, but everything else needs to fail. */
1605 if (s->event->state == SD_EVENT_FINISHED)
1606 return m == SD_EVENT_OFF ? 0 : -ESTALE;
1607
baf76283 1608 if (s->enabled == m)
fd38203a
LP
1609 return 0;
1610
baf76283 1611 if (m == SD_EVENT_OFF) {
fd38203a
LP
1612
1613 switch (s->type) {
1614
1615 case SOURCE_IO:
366e6411 1616 source_io_unregister(s);
baf76283 1617 s->enabled = m;
fd38203a
LP
1618 break;
1619
6a0f1f6d 1620 case SOURCE_TIME_REALTIME:
a8548816 1621 case SOURCE_TIME_BOOTTIME:
6a0f1f6d
LP
1622 case SOURCE_TIME_MONOTONIC:
1623 case SOURCE_TIME_REALTIME_ALARM:
1624 case SOURCE_TIME_BOOTTIME_ALARM: {
1625 struct clock_data *d;
fd38203a 1626
baf76283 1627 s->enabled = m;
6a0f1f6d
LP
1628 d = event_get_clock_data(s->event, s->type);
1629 assert(d);
1630
1631 prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
1632 prioq_reshuffle(d->latest, s, &s->time.latest_index);
212bbb17 1633 d->needs_rearm = true;
fd38203a 1634 break;
6a0f1f6d 1635 }
fd38203a
LP
1636
1637 case SOURCE_SIGNAL:
baf76283 1638 s->enabled = m;
4807d2d0 1639
9da4cb2b 1640 event_gc_signal_data(s->event, &s->priority, s->signal.sig);
fd38203a
LP
1641 break;
1642
1643 case SOURCE_CHILD:
baf76283 1644 s->enabled = m;
fd38203a 1645
baf76283
LP
1646 assert(s->event->n_enabled_child_sources > 0);
1647 s->event->n_enabled_child_sources--;
fd38203a 1648
9da4cb2b 1649 event_gc_signal_data(s->event, &s->priority, SIGCHLD);
fd38203a
LP
1650 break;
1651
6203e07a 1652 case SOURCE_EXIT:
305f78bf 1653 s->enabled = m;
6203e07a 1654 prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
305f78bf
LP
1655 break;
1656
1657 case SOURCE_DEFER:
6e9feda3 1658 case SOURCE_POST:
baf76283 1659 s->enabled = m;
fd38203a 1660 break;
9d3e3aa5 1661
6a0f1f6d 1662 default:
9d3e3aa5 1663 assert_not_reached("Wut? I shouldn't exist.");
fd38203a
LP
1664 }
1665
1666 } else {
1667 switch (s->type) {
1668
1669 case SOURCE_IO:
1670 r = source_io_register(s, m, s->io.events);
1671 if (r < 0)
1672 return r;
1673
baf76283 1674 s->enabled = m;
fd38203a
LP
1675 break;
1676
6a0f1f6d 1677 case SOURCE_TIME_REALTIME:
a8548816 1678 case SOURCE_TIME_BOOTTIME:
6a0f1f6d
LP
1679 case SOURCE_TIME_MONOTONIC:
1680 case SOURCE_TIME_REALTIME_ALARM:
1681 case SOURCE_TIME_BOOTTIME_ALARM: {
1682 struct clock_data *d;
fd38203a 1683
baf76283 1684 s->enabled = m;
6a0f1f6d
LP
1685 d = event_get_clock_data(s->event, s->type);
1686 assert(d);
1687
1688 prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
1689 prioq_reshuffle(d->latest, s, &s->time.latest_index);
212bbb17 1690 d->needs_rearm = true;
fd38203a 1691 break;
6a0f1f6d 1692 }
fd38203a
LP
1693
1694 case SOURCE_SIGNAL:
4807d2d0
ZJS
1695
1696 s->enabled = m;
9da4cb2b
LP
1697
1698 r = event_make_signal_data(s->event, s->signal.sig, NULL);
1699 if (r < 0) {
1700 s->enabled = SD_EVENT_OFF;
1701 event_gc_signal_data(s->event, &s->priority, s->signal.sig);
1702 return r;
1703 }
1704
fd38203a
LP
1705 break;
1706
1707 case SOURCE_CHILD:
4807d2d0 1708
9da4cb2b 1709 if (s->enabled == SD_EVENT_OFF)
4807d2d0 1710 s->event->n_enabled_child_sources++;
7a0d4a3d
DH
1711
1712 s->enabled = m;
9da4cb2b 1713
10edebf6 1714 r = event_make_signal_data(s->event, SIGCHLD, NULL);
9da4cb2b
LP
1715 if (r < 0) {
1716 s->enabled = SD_EVENT_OFF;
1717 s->event->n_enabled_child_sources--;
1718 event_gc_signal_data(s->event, &s->priority, SIGCHLD);
1719 return r;
1720 }
1721
fd38203a
LP
1722 break;
1723
6203e07a 1724 case SOURCE_EXIT:
305f78bf 1725 s->enabled = m;
6203e07a 1726 prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
305f78bf
LP
1727 break;
1728
1729 case SOURCE_DEFER:
6e9feda3 1730 case SOURCE_POST:
baf76283 1731 s->enabled = m;
fd38203a 1732 break;
9d3e3aa5 1733
6a0f1f6d 1734 default:
9d3e3aa5 1735 assert_not_reached("Wut? I shouldn't exist.");
fd38203a
LP
1736 }
1737 }
1738
1739 if (s->pending)
1740 prioq_reshuffle(s->event->pending, s, &s->pending_index);
1741
1742 if (s->prepare)
1743 prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
1744
1745 return 0;
1746}
1747
f7262a9f 1748_public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
305f78bf
LP
1749 assert_return(s, -EINVAL);
1750 assert_return(usec, -EINVAL);
6a0f1f6d 1751 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
305f78bf 1752 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1753
1754 *usec = s->time.next;
1755 return 0;
1756}
1757
f7262a9f 1758_public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
6a0f1f6d
LP
1759 struct clock_data *d;
1760
305f78bf 1761 assert_return(s, -EINVAL);
6a0f1f6d 1762 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
da7e457c 1763 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1764 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a 1765
fd38203a 1766 s->time.next = usec;
2576a19e 1767
0cc1125a 1768 source_set_pending(s, false);
fd38203a 1769
6a0f1f6d
LP
1770 d = event_get_clock_data(s->event, s->type);
1771 assert(d);
1772
1773 prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
1774 prioq_reshuffle(d->latest, s, &s->time.latest_index);
212bbb17 1775 d->needs_rearm = true;
fd38203a
LP
1776
1777 return 0;
1778}
1779
f7262a9f 1780_public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) {
305f78bf
LP
1781 assert_return(s, -EINVAL);
1782 assert_return(usec, -EINVAL);
6a0f1f6d 1783 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
305f78bf
LP
1784 assert_return(!event_pid_changed(s->event), -ECHILD);
1785
1786 *usec = s->time.accuracy;
1787 return 0;
1788}
1789
f7262a9f 1790_public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) {
6a0f1f6d
LP
1791 struct clock_data *d;
1792
305f78bf
LP
1793 assert_return(s, -EINVAL);
1794 assert_return(usec != (uint64_t) -1, -EINVAL);
6a0f1f6d 1795 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
da7e457c 1796 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1797 assert_return(!event_pid_changed(s->event), -ECHILD);
eaa3cbef
LP
1798
1799 if (usec == 0)
1800 usec = DEFAULT_ACCURACY_USEC;
1801
eaa3cbef
LP
1802 s->time.accuracy = usec;
1803
2576a19e
LP
1804 source_set_pending(s, false);
1805
6a0f1f6d
LP
1806 d = event_get_clock_data(s->event, s->type);
1807 assert(d);
1808
1809 prioq_reshuffle(d->latest, s, &s->time.latest_index);
212bbb17 1810 d->needs_rearm = true;
6a0f1f6d
LP
1811
1812 return 0;
1813}
1814
1815_public_ int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock) {
1816 assert_return(s, -EINVAL);
1817 assert_return(clock, -EINVAL);
1818 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
1819 assert_return(!event_pid_changed(s->event), -ECHILD);
eaa3cbef 1820
6a0f1f6d 1821 *clock = event_source_type_to_clock(s->type);
eaa3cbef
LP
1822 return 0;
1823}
1824
f7262a9f 1825_public_ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) {
4bee8012
LP
1826 assert_return(s, -EINVAL);
1827 assert_return(pid, -EINVAL);
1828 assert_return(s->type == SOURCE_CHILD, -EDOM);
1829 assert_return(!event_pid_changed(s->event), -ECHILD);
1830
1831 *pid = s->child.pid;
1832 return 0;
1833}
1834
718db961 1835_public_ int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback) {
fd38203a
LP
1836 int r;
1837
da7e457c 1838 assert_return(s, -EINVAL);
6203e07a 1839 assert_return(s->type != SOURCE_EXIT, -EDOM);
da7e457c
LP
1840 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
1841 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1842
1843 if (s->prepare == callback)
1844 return 0;
1845
1846 if (callback && s->prepare) {
1847 s->prepare = callback;
1848 return 0;
1849 }
1850
1851 r = prioq_ensure_allocated(&s->event->prepare, prepare_prioq_compare);
1852 if (r < 0)
1853 return r;
1854
1855 s->prepare = callback;
1856
1857 if (callback) {
1858 r = prioq_put(s->event->prepare, s, &s->prepare_index);
1859 if (r < 0)
1860 return r;
1861 } else
1862 prioq_remove(s->event->prepare, s, &s->prepare_index);
1863
1864 return 0;
1865}
1866
f7262a9f 1867_public_ void* sd_event_source_get_userdata(sd_event_source *s) {
da7e457c 1868 assert_return(s, NULL);
fd38203a
LP
1869
1870 return s->userdata;
1871}
1872
8f726607
LP
1873_public_ void *sd_event_source_set_userdata(sd_event_source *s, void *userdata) {
1874 void *ret;
1875
1876 assert_return(s, NULL);
1877
1878 ret = s->userdata;
1879 s->userdata = userdata;
1880
1881 return ret;
1882}
1883
c2ba3ad6
LP
1884static usec_t sleep_between(sd_event *e, usec_t a, usec_t b) {
1885 usec_t c;
1886 assert(e);
1887 assert(a <= b);
1888
1889 if (a <= 0)
1890 return 0;
393003e1
LP
1891 if (a >= USEC_INFINITY)
1892 return USEC_INFINITY;
c2ba3ad6
LP
1893
1894 if (b <= a + 1)
1895 return a;
1896
52444dc4
LP
1897 initialize_perturb(e);
1898
c2ba3ad6
LP
1899 /*
1900 Find a good time to wake up again between times a and b. We
1901 have two goals here:
1902
1903 a) We want to wake up as seldom as possible, hence prefer
1904 later times over earlier times.
1905
1906 b) But if we have to wake up, then let's make sure to
1907 dispatch as much as possible on the entire system.
1908
1909 We implement this by waking up everywhere at the same time
850516e0 1910 within any given minute if we can, synchronised via the
c2ba3ad6 1911 perturbation value determined from the boot ID. If we can't,
ba276c81
LP
1912 then we try to find the same spot in every 10s, then 1s and
1913 then 250ms step. Otherwise, we pick the last possible time
1914 to wake up.
c2ba3ad6
LP
1915 */
1916
850516e0
LP
1917 c = (b / USEC_PER_MINUTE) * USEC_PER_MINUTE + e->perturb;
1918 if (c >= b) {
1919 if (_unlikely_(c < USEC_PER_MINUTE))
1920 return b;
1921
1922 c -= USEC_PER_MINUTE;
1923 }
1924
ba276c81
LP
1925 if (c >= a)
1926 return c;
1927
1928 c = (b / (USEC_PER_SEC*10)) * (USEC_PER_SEC*10) + (e->perturb % (USEC_PER_SEC*10));
1929 if (c >= b) {
1930 if (_unlikely_(c < USEC_PER_SEC*10))
1931 return b;
1932
1933 c -= USEC_PER_SEC*10;
1934 }
1935
850516e0
LP
1936 if (c >= a)
1937 return c;
1938
1939 c = (b / USEC_PER_SEC) * USEC_PER_SEC + (e->perturb % USEC_PER_SEC);
c2ba3ad6
LP
1940 if (c >= b) {
1941 if (_unlikely_(c < USEC_PER_SEC))
1942 return b;
1943
1944 c -= USEC_PER_SEC;
1945 }
1946
1947 if (c >= a)
1948 return c;
1949
1950 c = (b / (USEC_PER_MSEC*250)) * (USEC_PER_MSEC*250) + (e->perturb % (USEC_PER_MSEC*250));
1951 if (c >= b) {
1952 if (_unlikely_(c < USEC_PER_MSEC*250))
1953 return b;
1954
1955 c -= USEC_PER_MSEC*250;
1956 }
1957
1958 if (c >= a)
1959 return c;
1960
1961 return b;
1962}
1963
fd38203a
LP
1964static int event_arm_timer(
1965 sd_event *e,
6a0f1f6d 1966 struct clock_data *d) {
fd38203a
LP
1967
1968 struct itimerspec its = {};
c2ba3ad6
LP
1969 sd_event_source *a, *b;
1970 usec_t t;
fd38203a
LP
1971 int r;
1972
cde93897 1973 assert(e);
6a0f1f6d 1974 assert(d);
fd38203a 1975
d06441da 1976 if (!d->needs_rearm)
212bbb17
TG
1977 return 0;
1978 else
1979 d->needs_rearm = false;
1980
6a0f1f6d 1981 a = prioq_peek(d->earliest);
393003e1 1982 if (!a || a->enabled == SD_EVENT_OFF || a->time.next == USEC_INFINITY) {
72aedc1e 1983
6a0f1f6d 1984 if (d->fd < 0)
c57b5ca3
LP
1985 return 0;
1986
3a43da28 1987 if (d->next == USEC_INFINITY)
72aedc1e
LP
1988 return 0;
1989
1990 /* disarm */
6a0f1f6d 1991 r = timerfd_settime(d->fd, TFD_TIMER_ABSTIME, &its, NULL);
72aedc1e
LP
1992 if (r < 0)
1993 return r;
1994
3a43da28 1995 d->next = USEC_INFINITY;
fd38203a 1996 return 0;
72aedc1e 1997 }
fd38203a 1998
6a0f1f6d 1999 b = prioq_peek(d->latest);
baf76283 2000 assert_se(b && b->enabled != SD_EVENT_OFF);
c2ba3ad6 2001
1bce0ffa 2002 t = sleep_between(e, a->time.next, time_event_source_latest(b));
6a0f1f6d 2003 if (d->next == t)
fd38203a
LP
2004 return 0;
2005
6a0f1f6d 2006 assert_se(d->fd >= 0);
fd38203a 2007
c2ba3ad6 2008 if (t == 0) {
fd38203a
LP
2009 /* We don' want to disarm here, just mean some time looooong ago. */
2010 its.it_value.tv_sec = 0;
2011 its.it_value.tv_nsec = 1;
2012 } else
c2ba3ad6 2013 timespec_store(&its.it_value, t);
fd38203a 2014
6a0f1f6d 2015 r = timerfd_settime(d->fd, TFD_TIMER_ABSTIME, &its, NULL);
fd38203a 2016 if (r < 0)
cde93897 2017 return -errno;
fd38203a 2018
6a0f1f6d 2019 d->next = t;
fd38203a
LP
2020 return 0;
2021}
2022
9a800b56 2023static int process_io(sd_event *e, sd_event_source *s, uint32_t revents) {
fd38203a
LP
2024 assert(e);
2025 assert(s);
2026 assert(s->type == SOURCE_IO);
2027
9a800b56
LP
2028 /* If the event source was already pending, we just OR in the
2029 * new revents, otherwise we reset the value. The ORing is
2030 * necessary to handle EPOLLONESHOT events properly where
2031 * readability might happen independently of writability, and
2032 * we need to keep track of both */
2033
2034 if (s->pending)
2035 s->io.revents |= revents;
2036 else
2037 s->io.revents = revents;
fd38203a 2038
fd38203a
LP
2039 return source_set_pending(s, true);
2040}
2041
72aedc1e 2042static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) {
fd38203a
LP
2043 uint64_t x;
2044 ssize_t ss;
2045
2046 assert(e);
da7e457c 2047 assert(fd >= 0);
72aedc1e 2048
305f78bf 2049 assert_return(events == EPOLLIN, -EIO);
fd38203a
LP
2050
2051 ss = read(fd, &x, sizeof(x));
2052 if (ss < 0) {
945c2931 2053 if (IN_SET(errno, EAGAIN, EINTR))
fd38203a
LP
2054 return 0;
2055
2056 return -errno;
2057 }
2058
8d35dae7 2059 if (_unlikely_(ss != sizeof(x)))
fd38203a
LP
2060 return -EIO;
2061
cde93897 2062 if (next)
3a43da28 2063 *next = USEC_INFINITY;
72aedc1e 2064
fd38203a
LP
2065 return 0;
2066}
2067
305f78bf
LP
2068static int process_timer(
2069 sd_event *e,
2070 usec_t n,
6a0f1f6d 2071 struct clock_data *d) {
305f78bf 2072
fd38203a
LP
2073 sd_event_source *s;
2074 int r;
2075
2076 assert(e);
6a0f1f6d 2077 assert(d);
fd38203a
LP
2078
2079 for (;;) {
6a0f1f6d 2080 s = prioq_peek(d->earliest);
fd38203a
LP
2081 if (!s ||
2082 s->time.next > n ||
baf76283 2083 s->enabled == SD_EVENT_OFF ||
fd38203a
LP
2084 s->pending)
2085 break;
2086
2087 r = source_set_pending(s, true);
2088 if (r < 0)
2089 return r;
2090
6a0f1f6d
LP
2091 prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
2092 prioq_reshuffle(d->latest, s, &s->time.latest_index);
e07bbb7c 2093 d->needs_rearm = true;
fd38203a
LP
2094 }
2095
2096 return 0;
2097}
2098
2099static int process_child(sd_event *e) {
2100 sd_event_source *s;
2101 Iterator i;
2102 int r;
2103
2104 assert(e);
2105
c2ba3ad6
LP
2106 e->need_process_child = false;
2107
fd38203a
LP
2108 /*
2109 So, this is ugly. We iteratively invoke waitid() with P_PID
2110 + WNOHANG for each PID we wait for, instead of using
2111 P_ALL. This is because we only want to get child
2112 information of very specific child processes, and not all
2113 of them. We might not have processed the SIGCHLD even of a
2114 previous invocation and we don't want to maintain a
2115 unbounded *per-child* event queue, hence we really don't
2116 want anything flushed out of the kernel's queue that we
2117 don't care about. Since this is O(n) this means that if you
2118 have a lot of processes you probably want to handle SIGCHLD
2119 yourself.
08cd1552
LP
2120
2121 We do not reap the children here (by using WNOWAIT), this
2122 is only done after the event source is dispatched so that
2123 the callback still sees the process as a zombie.
fd38203a
LP
2124 */
2125
2126 HASHMAP_FOREACH(s, e->child_sources, i) {
2127 assert(s->type == SOURCE_CHILD);
2128
2129 if (s->pending)
2130 continue;
2131
baf76283 2132 if (s->enabled == SD_EVENT_OFF)
fd38203a
LP
2133 continue;
2134
2135 zero(s->child.siginfo);
08cd1552
LP
2136 r = waitid(P_PID, s->child.pid, &s->child.siginfo,
2137 WNOHANG | (s->child.options & WEXITED ? WNOWAIT : 0) | s->child.options);
fd38203a
LP
2138 if (r < 0)
2139 return -errno;
2140
2141 if (s->child.siginfo.si_pid != 0) {
945c2931 2142 bool zombie = IN_SET(s->child.siginfo.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED);
08cd1552
LP
2143
2144 if (!zombie && (s->child.options & WEXITED)) {
2145 /* If the child isn't dead then let's
2146 * immediately remove the state change
2147 * from the queue, since there's no
2148 * benefit in leaving it queued */
2149
2150 assert(s->child.options & (WSTOPPED|WCONTINUED));
2151 waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|(s->child.options & (WSTOPPED|WCONTINUED)));
2152 }
2153
fd38203a
LP
2154 r = source_set_pending(s, true);
2155 if (r < 0)
2156 return r;
2157 }
2158 }
2159
fd38203a
LP
2160 return 0;
2161}
2162
9da4cb2b 2163static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
fd38203a 2164 bool read_one = false;
fd38203a
LP
2165 int r;
2166
da7e457c 2167 assert(e);
305f78bf 2168 assert_return(events == EPOLLIN, -EIO);
fd38203a 2169
9da4cb2b
LP
2170 /* If there's a signal queued on this priority and SIGCHLD is
2171 on this priority too, then make sure to recheck the
2172 children we watch. This is because we only ever dequeue
2173 the first signal per priority, and if we dequeue one, and
2174 SIGCHLD might be enqueued later we wouldn't know, but we
2175 might have higher priority children we care about hence we
2176 need to check that explicitly. */
2177
2178 if (sigismember(&d->sigset, SIGCHLD))
2179 e->need_process_child = true;
2180
2181 /* If there's already an event source pending for this
2182 * priority we don't read another */
2183 if (d->current)
2184 return 0;
2185
fd38203a 2186 for (;;) {
0eb2e0e3 2187 struct signalfd_siginfo si;
7057bd99 2188 ssize_t n;
92daebc0 2189 sd_event_source *s = NULL;
fd38203a 2190
9da4cb2b 2191 n = read(d->fd, &si, sizeof(si));
7057bd99 2192 if (n < 0) {
945c2931 2193 if (IN_SET(errno, EAGAIN, EINTR))
fd38203a
LP
2194 return read_one;
2195
2196 return -errno;
2197 }
2198
7057bd99 2199 if (_unlikely_(n != sizeof(si)))
fd38203a
LP
2200 return -EIO;
2201
6eb7c172 2202 assert(SIGNAL_VALID(si.ssi_signo));
7057bd99 2203
fd38203a
LP
2204 read_one = true;
2205
92daebc0
LP
2206 if (e->signal_sources)
2207 s = e->signal_sources[si.ssi_signo];
92daebc0
LP
2208 if (!s)
2209 continue;
9da4cb2b
LP
2210 if (s->pending)
2211 continue;
fd38203a
LP
2212
2213 s->signal.siginfo = si;
9da4cb2b
LP
2214 d->current = s;
2215
fd38203a
LP
2216 r = source_set_pending(s, true);
2217 if (r < 0)
2218 return r;
9da4cb2b
LP
2219
2220 return 1;
fd38203a 2221 }
fd38203a
LP
2222}
2223
2224static int source_dispatch(sd_event_source *s) {
8f5c235d 2225 EventSourceType saved_type;
fe8245eb 2226 int r = 0;
fd38203a
LP
2227
2228 assert(s);
6203e07a 2229 assert(s->pending || s->type == SOURCE_EXIT);
fd38203a 2230
8f5c235d
LP
2231 /* Save the event source type, here, so that we still know it after the event callback which might invalidate
2232 * the event. */
2233 saved_type = s->type;
2234
945c2931 2235 if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
da7e457c
LP
2236 r = source_set_pending(s, false);
2237 if (r < 0)
2238 return r;
2239 }
fd38203a 2240
6e9feda3
LP
2241 if (s->type != SOURCE_POST) {
2242 sd_event_source *z;
2243 Iterator i;
2244
2245 /* If we execute a non-post source, let's mark all
2246 * post sources as pending */
2247
2248 SET_FOREACH(z, s->event->post_sources, i) {
2249 if (z->enabled == SD_EVENT_OFF)
2250 continue;
2251
2252 r = source_set_pending(z, true);
2253 if (r < 0)
2254 return r;
2255 }
2256 }
2257
baf76283
LP
2258 if (s->enabled == SD_EVENT_ONESHOT) {
2259 r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
fd38203a
LP
2260 if (r < 0)
2261 return r;
2262 }
2263
12179984 2264 s->dispatching = true;
b7484e2a 2265
fd38203a
LP
2266 switch (s->type) {
2267
2268 case SOURCE_IO:
2269 r = s->io.callback(s, s->io.fd, s->io.revents, s->userdata);
2270 break;
2271
6a0f1f6d 2272 case SOURCE_TIME_REALTIME:
a8548816 2273 case SOURCE_TIME_BOOTTIME:
6a0f1f6d
LP
2274 case SOURCE_TIME_MONOTONIC:
2275 case SOURCE_TIME_REALTIME_ALARM:
2276 case SOURCE_TIME_BOOTTIME_ALARM:
fd38203a
LP
2277 r = s->time.callback(s, s->time.next, s->userdata);
2278 break;
2279
2280 case SOURCE_SIGNAL:
2281 r = s->signal.callback(s, &s->signal.siginfo, s->userdata);
2282 break;
2283
08cd1552
LP
2284 case SOURCE_CHILD: {
2285 bool zombie;
2286
945c2931 2287 zombie = IN_SET(s->child.siginfo.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED);
08cd1552 2288
fd38203a 2289 r = s->child.callback(s, &s->child.siginfo, s->userdata);
08cd1552
LP
2290
2291 /* Now, reap the PID for good. */
2292 if (zombie)
2293 waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|WEXITED);
2294
fd38203a 2295 break;
08cd1552 2296 }
fd38203a
LP
2297
2298 case SOURCE_DEFER:
2299 r = s->defer.callback(s, s->userdata);
2300 break;
da7e457c 2301
6e9feda3
LP
2302 case SOURCE_POST:
2303 r = s->post.callback(s, s->userdata);
2304 break;
2305
6203e07a
LP
2306 case SOURCE_EXIT:
2307 r = s->exit.callback(s, s->userdata);
da7e457c 2308 break;
9d3e3aa5
LP
2309
2310 case SOURCE_WATCHDOG:
a71fe8b8 2311 case _SOURCE_EVENT_SOURCE_TYPE_MAX:
9f2a50a3 2312 case _SOURCE_EVENT_SOURCE_TYPE_INVALID:
9d3e3aa5 2313 assert_not_reached("Wut? I shouldn't exist.");
fd38203a
LP
2314 }
2315
12179984
LP
2316 s->dispatching = false;
2317
55cbfaa5
DM
2318 if (r < 0)
2319 log_debug_errno(r, "Event source %s (type %s) returned error, disabling: %m",
8f5c235d 2320 strna(s->description), event_source_type_to_string(saved_type));
12179984
LP
2321
2322 if (s->n_ref == 0)
2323 source_free(s);
2324 else if (r < 0)
6203e07a 2325 sd_event_source_set_enabled(s, SD_EVENT_OFF);
b7484e2a 2326
6203e07a 2327 return 1;
fd38203a
LP
2328}
2329
2330static int event_prepare(sd_event *e) {
2331 int r;
2332
2333 assert(e);
2334
2335 for (;;) {
2336 sd_event_source *s;
2337
2338 s = prioq_peek(e->prepare);
baf76283 2339 if (!s || s->prepare_iteration == e->iteration || s->enabled == SD_EVENT_OFF)
fd38203a
LP
2340 break;
2341
2342 s->prepare_iteration = e->iteration;
2343 r = prioq_reshuffle(e->prepare, s, &s->prepare_index);
2344 if (r < 0)
2345 return r;
2346
2347 assert(s->prepare);
12179984
LP
2348
2349 s->dispatching = true;
fd38203a 2350 r = s->prepare(s, s->userdata);
12179984
LP
2351 s->dispatching = false;
2352
55cbfaa5
DM
2353 if (r < 0)
2354 log_debug_errno(r, "Prepare callback of event source %s (type %s) returned error, disabling: %m",
2355 strna(s->description), event_source_type_to_string(s->type));
fd38203a 2356
12179984
LP
2357 if (s->n_ref == 0)
2358 source_free(s);
2359 else if (r < 0)
2360 sd_event_source_set_enabled(s, SD_EVENT_OFF);
fd38203a
LP
2361 }
2362
2363 return 0;
2364}
2365
6203e07a 2366static int dispatch_exit(sd_event *e) {
da7e457c
LP
2367 sd_event_source *p;
2368 int r;
2369
2370 assert(e);
2371
6203e07a 2372 p = prioq_peek(e->exit);
baf76283 2373 if (!p || p->enabled == SD_EVENT_OFF) {
da7e457c
LP
2374 e->state = SD_EVENT_FINISHED;
2375 return 0;
2376 }
2377
2378 sd_event_ref(e);
2379 e->iteration++;
6203e07a 2380 e->state = SD_EVENT_EXITING;
da7e457c
LP
2381
2382 r = source_dispatch(p);
2383
2b0c9ef7 2384 e->state = SD_EVENT_INITIAL;
da7e457c
LP
2385 sd_event_unref(e);
2386
2387 return r;
2388}
2389
c2ba3ad6
LP
2390static sd_event_source* event_next_pending(sd_event *e) {
2391 sd_event_source *p;
2392
da7e457c
LP
2393 assert(e);
2394
c2ba3ad6
LP
2395 p = prioq_peek(e->pending);
2396 if (!p)
2397 return NULL;
2398
baf76283 2399 if (p->enabled == SD_EVENT_OFF)
c2ba3ad6
LP
2400 return NULL;
2401
2402 return p;
2403}
2404
cde93897
LP
2405static int arm_watchdog(sd_event *e) {
2406 struct itimerspec its = {};
2407 usec_t t;
2408 int r;
2409
2410 assert(e);
2411 assert(e->watchdog_fd >= 0);
2412
2413 t = sleep_between(e,
2414 e->watchdog_last + (e->watchdog_period / 2),
2415 e->watchdog_last + (e->watchdog_period * 3 / 4));
2416
2417 timespec_store(&its.it_value, t);
2418
75145780
LP
2419 /* Make sure we never set the watchdog to 0, which tells the
2420 * kernel to disable it. */
2421 if (its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0)
2422 its.it_value.tv_nsec = 1;
2423
cde93897
LP
2424 r = timerfd_settime(e->watchdog_fd, TFD_TIMER_ABSTIME, &its, NULL);
2425 if (r < 0)
2426 return -errno;
2427
2428 return 0;
2429}
2430
2431static int process_watchdog(sd_event *e) {
2432 assert(e);
2433
2434 if (!e->watchdog)
2435 return 0;
2436
2437 /* Don't notify watchdog too often */
2438 if (e->watchdog_last + e->watchdog_period / 4 > e->timestamp.monotonic)
2439 return 0;
2440
2441 sd_notify(false, "WATCHDOG=1");
2442 e->watchdog_last = e->timestamp.monotonic;
2443
2444 return arm_watchdog(e);
2445}
2446
c45a5a74
TG
2447_public_ int sd_event_prepare(sd_event *e) {
2448 int r;
fd38203a 2449
da7e457c
LP
2450 assert_return(e, -EINVAL);
2451 assert_return(!event_pid_changed(e), -ECHILD);
2452 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
2b0c9ef7 2453 assert_return(e->state == SD_EVENT_INITIAL, -EBUSY);
da7e457c 2454
6203e07a 2455 if (e->exit_requested)
c45a5a74 2456 goto pending;
fd38203a
LP
2457
2458 e->iteration++;
2459
0be6c2f6 2460 e->state = SD_EVENT_PREPARING;
fd38203a 2461 r = event_prepare(e);
0be6c2f6 2462 e->state = SD_EVENT_INITIAL;
fd38203a 2463 if (r < 0)
c45a5a74 2464 return r;
fd38203a 2465
6a0f1f6d
LP
2466 r = event_arm_timer(e, &e->realtime);
2467 if (r < 0)
c45a5a74 2468 return r;
6a0f1f6d 2469
a8548816
TG
2470 r = event_arm_timer(e, &e->boottime);
2471 if (r < 0)
c45a5a74 2472 return r;
a8548816 2473
6a0f1f6d
LP
2474 r = event_arm_timer(e, &e->monotonic);
2475 if (r < 0)
c45a5a74 2476 return r;
6a0f1f6d
LP
2477
2478 r = event_arm_timer(e, &e->realtime_alarm);
1b5995b0 2479 if (r < 0)
c45a5a74 2480 return r;
fd38203a 2481
6a0f1f6d 2482 r = event_arm_timer(e, &e->boottime_alarm);
1b5995b0 2483 if (r < 0)
c45a5a74 2484 return r;
fd38203a 2485
1b5995b0 2486 if (event_next_pending(e) || e->need_process_child)
c45a5a74
TG
2487 goto pending;
2488
2b0c9ef7 2489 e->state = SD_EVENT_ARMED;
c45a5a74
TG
2490
2491 return 0;
2492
2493pending:
2b0c9ef7 2494 e->state = SD_EVENT_ARMED;
6d148a84
TG
2495 r = sd_event_wait(e, 0);
2496 if (r == 0)
2b0c9ef7 2497 e->state = SD_EVENT_ARMED;
6d148a84
TG
2498
2499 return r;
c45a5a74
TG
2500}
2501
2502_public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
2503 struct epoll_event *ev_queue;
2504 unsigned ev_queue_max;
2505 int r, m, i;
2506
2507 assert_return(e, -EINVAL);
2508 assert_return(!event_pid_changed(e), -ECHILD);
2509 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
2b0c9ef7 2510 assert_return(e->state == SD_EVENT_ARMED, -EBUSY);
c45a5a74
TG
2511
2512 if (e->exit_requested) {
2513 e->state = SD_EVENT_PENDING;
2514 return 1;
2515 }
6a0f1f6d 2516
1c724e9e 2517 ev_queue_max = MAX(e->n_sources, 1u);
15b38f93 2518 ev_queue = newa(struct epoll_event, ev_queue_max);
fd38203a 2519
15b38f93 2520 m = epoll_wait(e->epoll_fd, ev_queue, ev_queue_max,
c2ba3ad6 2521 timeout == (uint64_t) -1 ? -1 : (int) ((timeout + USEC_PER_MSEC - 1) / USEC_PER_MSEC));
da7e457c 2522 if (m < 0) {
c45a5a74
TG
2523 if (errno == EINTR) {
2524 e->state = SD_EVENT_PENDING;
2525 return 1;
2526 }
2527
2528 r = -errno;
da7e457c
LP
2529 goto finish;
2530 }
fd38203a 2531
e475d10c 2532 triple_timestamp_get(&e->timestamp);
fd38203a
LP
2533
2534 for (i = 0; i < m; i++) {
2535
9da4cb2b 2536 if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_WATCHDOG))
cde93897 2537 r = flush_timer(e, e->watchdog_fd, ev_queue[i].events, NULL);
9da4cb2b
LP
2538 else {
2539 WakeupType *t = ev_queue[i].data.ptr;
2540
2541 switch (*t) {
2542
2543 case WAKEUP_EVENT_SOURCE:
2544 r = process_io(e, ev_queue[i].data.ptr, ev_queue[i].events);
2545 break;
fd38203a 2546
9da4cb2b
LP
2547 case WAKEUP_CLOCK_DATA: {
2548 struct clock_data *d = ev_queue[i].data.ptr;
2549 r = flush_timer(e, d->fd, ev_queue[i].events, &d->next);
2550 break;
2551 }
2552
2553 case WAKEUP_SIGNAL_DATA:
2554 r = process_signal(e, ev_queue[i].data.ptr, ev_queue[i].events);
2555 break;
2556
2557 default:
2558 assert_not_reached("Invalid wake-up pointer");
2559 }
2560 }
fd38203a 2561 if (r < 0)
da7e457c 2562 goto finish;
fd38203a
LP
2563 }
2564
cde93897
LP
2565 r = process_watchdog(e);
2566 if (r < 0)
2567 goto finish;
2568
6a0f1f6d
LP
2569 r = process_timer(e, e->timestamp.realtime, &e->realtime);
2570 if (r < 0)
2571 goto finish;
2572
e475d10c 2573 r = process_timer(e, e->timestamp.boottime, &e->boottime);
a8548816
TG
2574 if (r < 0)
2575 goto finish;
2576
6a0f1f6d
LP
2577 r = process_timer(e, e->timestamp.monotonic, &e->monotonic);
2578 if (r < 0)
2579 goto finish;
2580
2581 r = process_timer(e, e->timestamp.realtime, &e->realtime_alarm);
fd38203a 2582 if (r < 0)
da7e457c 2583 goto finish;
fd38203a 2584
e475d10c 2585 r = process_timer(e, e->timestamp.boottime, &e->boottime_alarm);
fd38203a 2586 if (r < 0)
da7e457c 2587 goto finish;
fd38203a 2588
c2ba3ad6 2589 if (e->need_process_child) {
fd38203a
LP
2590 r = process_child(e);
2591 if (r < 0)
da7e457c 2592 goto finish;
fd38203a
LP
2593 }
2594
c45a5a74
TG
2595 if (event_next_pending(e)) {
2596 e->state = SD_EVENT_PENDING;
2597
2598 return 1;
da7e457c
LP
2599 }
2600
c45a5a74 2601 r = 0;
fd38203a 2602
da7e457c 2603finish:
2b0c9ef7 2604 e->state = SD_EVENT_INITIAL;
da7e457c
LP
2605
2606 return r;
fd38203a
LP
2607}
2608
c45a5a74
TG
2609_public_ int sd_event_dispatch(sd_event *e) {
2610 sd_event_source *p;
2611 int r;
2612
2613 assert_return(e, -EINVAL);
2614 assert_return(!event_pid_changed(e), -ECHILD);
2615 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
2616 assert_return(e->state == SD_EVENT_PENDING, -EBUSY);
2617
2618 if (e->exit_requested)
2619 return dispatch_exit(e);
2620
2621 p = event_next_pending(e);
2622 if (p) {
2623 sd_event_ref(e);
2624
2625 e->state = SD_EVENT_RUNNING;
2626 r = source_dispatch(p);
2b0c9ef7 2627 e->state = SD_EVENT_INITIAL;
c45a5a74
TG
2628
2629 sd_event_unref(e);
2630
2631 return r;
2632 }
2633
2b0c9ef7 2634 e->state = SD_EVENT_INITIAL;
c45a5a74
TG
2635
2636 return 1;
2637}
2638
34b87517
VC
2639static void event_log_delays(sd_event *e) {
2640 char b[ELEMENTSOF(e->delays) * DECIMAL_STR_MAX(unsigned) + 1];
34a6843d
VC
2641 unsigned i;
2642 int o;
34b87517
VC
2643
2644 for (i = o = 0; i < ELEMENTSOF(e->delays); i++) {
2645 o += snprintf(&b[o], sizeof(b) - o, "%u ", e->delays[i]);
2646 e->delays[i] = 0;
2647 }
34a6843d 2648 log_debug("Event loop iterations: %.*s", o, b);
34b87517
VC
2649}
2650
c45a5a74
TG
2651_public_ int sd_event_run(sd_event *e, uint64_t timeout) {
2652 int r;
2653
2654 assert_return(e, -EINVAL);
2655 assert_return(!event_pid_changed(e), -ECHILD);
2656 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
2b0c9ef7 2657 assert_return(e->state == SD_EVENT_INITIAL, -EBUSY);
c45a5a74 2658
34b87517
VC
2659 if (e->profile_delays && e->last_run) {
2660 usec_t this_run;
2661 unsigned l;
2662
2663 this_run = now(CLOCK_MONOTONIC);
2664
2665 l = u64log2(this_run - e->last_run);
2666 assert(l < sizeof(e->delays));
2667 e->delays[l]++;
2668
2669 if (this_run - e->last_log >= 5*USEC_PER_SEC) {
2670 event_log_delays(e);
2671 e->last_log = this_run;
2672 }
2673 }
2674
c45a5a74 2675 r = sd_event_prepare(e);
53bac4e0
LP
2676 if (r == 0)
2677 /* There was nothing? Then wait... */
2678 r = sd_event_wait(e, timeout);
c45a5a74 2679
34b87517
VC
2680 if (e->profile_delays)
2681 e->last_run = now(CLOCK_MONOTONIC);
2682
02d30981 2683 if (r > 0) {
53bac4e0 2684 /* There's something now, then let's dispatch it */
02d30981
TG
2685 r = sd_event_dispatch(e);
2686 if (r < 0)
2687 return r;
53bac4e0
LP
2688
2689 return 1;
2690 }
2691
2692 return r;
c45a5a74
TG
2693}
2694
f7262a9f 2695_public_ int sd_event_loop(sd_event *e) {
fd38203a
LP
2696 int r;
2697
da7e457c
LP
2698 assert_return(e, -EINVAL);
2699 assert_return(!event_pid_changed(e), -ECHILD);
2b0c9ef7 2700 assert_return(e->state == SD_EVENT_INITIAL, -EBUSY);
da7e457c
LP
2701
2702 sd_event_ref(e);
fd38203a 2703
da7e457c 2704 while (e->state != SD_EVENT_FINISHED) {
fd38203a
LP
2705 r = sd_event_run(e, (uint64_t) -1);
2706 if (r < 0)
da7e457c 2707 goto finish;
fd38203a
LP
2708 }
2709
6203e07a 2710 r = e->exit_code;
da7e457c
LP
2711
2712finish:
2713 sd_event_unref(e);
2714 return r;
fd38203a
LP
2715}
2716
9b364545
TG
2717_public_ int sd_event_get_fd(sd_event *e) {
2718
2719 assert_return(e, -EINVAL);
2720 assert_return(!event_pid_changed(e), -ECHILD);
2721
2722 return e->epoll_fd;
2723}
2724
f7262a9f 2725_public_ int sd_event_get_state(sd_event *e) {
da7e457c
LP
2726 assert_return(e, -EINVAL);
2727 assert_return(!event_pid_changed(e), -ECHILD);
2728
2729 return e->state;
2730}
2731
6203e07a 2732_public_ int sd_event_get_exit_code(sd_event *e, int *code) {
da7e457c 2733 assert_return(e, -EINVAL);
6203e07a 2734 assert_return(code, -EINVAL);
da7e457c 2735 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 2736
6203e07a
LP
2737 if (!e->exit_requested)
2738 return -ENODATA;
2739
2740 *code = e->exit_code;
2741 return 0;
fd38203a
LP
2742}
2743
6203e07a 2744_public_ int sd_event_exit(sd_event *e, int code) {
da7e457c
LP
2745 assert_return(e, -EINVAL);
2746 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
2747 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 2748
6203e07a
LP
2749 e->exit_requested = true;
2750 e->exit_code = code;
2751
fd38203a
LP
2752 return 0;
2753}
46e8c825 2754
6a0f1f6d 2755_public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) {
46e8c825
LP
2756 assert_return(e, -EINVAL);
2757 assert_return(usec, -EINVAL);
46e8c825
LP
2758 assert_return(!event_pid_changed(e), -ECHILD);
2759
e475d10c
LP
2760 if (!TRIPLE_TIMESTAMP_HAS_CLOCK(clock))
2761 return -EOPNOTSUPP;
2762
2763 /* Generate a clean error in case CLOCK_BOOTTIME is not available. Note that don't use clock_supported() here,
2764 * for a reason: there are systems where CLOCK_BOOTTIME is supported, but CLOCK_BOOTTIME_ALARM is not, but for
2765 * the purpose of getting the time this doesn't matter. */
3411372e
LP
2766 if (IN_SET(clock, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) && !clock_boottime_supported())
2767 return -EOPNOTSUPP;
2768
e475d10c 2769 if (!triple_timestamp_is_set(&e->timestamp)) {
38a03f06
LP
2770 /* Implicitly fall back to now() if we never ran
2771 * before and thus have no cached time. */
2772 *usec = now(clock);
2773 return 1;
2774 }
46e8c825 2775
e475d10c 2776 *usec = triple_timestamp_by_clock(&e->timestamp, clock);
46e8c825
LP
2777 return 0;
2778}
afc6adb5
LP
2779
2780_public_ int sd_event_default(sd_event **ret) {
2781
ec202eae 2782 static thread_local sd_event *default_event = NULL;
39883f62 2783 sd_event *e = NULL;
afc6adb5
LP
2784 int r;
2785
2786 if (!ret)
2787 return !!default_event;
2788
2789 if (default_event) {
2790 *ret = sd_event_ref(default_event);
2791 return 0;
2792 }
2793
2794 r = sd_event_new(&e);
2795 if (r < 0)
2796 return r;
2797
2798 e->default_event_ptr = &default_event;
2799 e->tid = gettid();
2800 default_event = e;
2801
2802 *ret = e;
2803 return 1;
2804}
2805
2806_public_ int sd_event_get_tid(sd_event *e, pid_t *tid) {
2807 assert_return(e, -EINVAL);
2808 assert_return(tid, -EINVAL);
76b54375 2809 assert_return(!event_pid_changed(e), -ECHILD);
afc6adb5 2810
76b54375
LP
2811 if (e->tid != 0) {
2812 *tid = e->tid;
2813 return 0;
2814 }
2815
2816 return -ENXIO;
afc6adb5 2817}
cde93897
LP
2818
2819_public_ int sd_event_set_watchdog(sd_event *e, int b) {
2820 int r;
2821
2822 assert_return(e, -EINVAL);
8f726607 2823 assert_return(!event_pid_changed(e), -ECHILD);
cde93897
LP
2824
2825 if (e->watchdog == !!b)
2826 return e->watchdog;
2827
2828 if (b) {
2829 struct epoll_event ev = {};
cde93897 2830
09812eb7
LP
2831 r = sd_watchdog_enabled(false, &e->watchdog_period);
2832 if (r <= 0)
cde93897 2833 return r;
cde93897
LP
2834
2835 /* Issue first ping immediately */
2836 sd_notify(false, "WATCHDOG=1");
2837 e->watchdog_last = now(CLOCK_MONOTONIC);
2838
2839 e->watchdog_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
2840 if (e->watchdog_fd < 0)
2841 return -errno;
2842
2843 r = arm_watchdog(e);
2844 if (r < 0)
2845 goto fail;
2846
2847 ev.events = EPOLLIN;
2848 ev.data.ptr = INT_TO_PTR(SOURCE_WATCHDOG);
2849
2850 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, e->watchdog_fd, &ev);
2851 if (r < 0) {
2852 r = -errno;
2853 goto fail;
2854 }
2855
2856 } else {
2857 if (e->watchdog_fd >= 0) {
2858 epoll_ctl(e->epoll_fd, EPOLL_CTL_DEL, e->watchdog_fd, NULL);
03e334a1 2859 e->watchdog_fd = safe_close(e->watchdog_fd);
cde93897
LP
2860 }
2861 }
2862
2863 e->watchdog = !!b;
2864 return e->watchdog;
2865
2866fail:
03e334a1 2867 e->watchdog_fd = safe_close(e->watchdog_fd);
cde93897
LP
2868 return r;
2869}
8f726607
LP
2870
2871_public_ int sd_event_get_watchdog(sd_event *e) {
2872 assert_return(e, -EINVAL);
2873 assert_return(!event_pid_changed(e), -ECHILD);
2874
2875 return e->watchdog;
2876}
60a3b1e1
LP
2877
2878_public_ int sd_event_get_iteration(sd_event *e, uint64_t *ret) {
2879 assert_return(e, -EINVAL);
2880 assert_return(!event_pid_changed(e), -ECHILD);
2881
2882 *ret = e->iteration;
2883 return 0;
2884}