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