]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-event/sd-event.c
util: add usec_add() which adds two usec_t values with overflow handling
[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 451 if (secure_getenv("SD_EVENT_PROFILE_DELAYS")) {
34a6843d 452 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
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);
90f604d1
ZJS
664 if (r < 0) {
665 free(d);
9da4cb2b 666 return r;
90f604d1 667 }
f95387cd 668
9da4cb2b
LP
669 added = true;
670 }
671
672 ss_copy = d->sigset;
673 assert_se(sigaddset(&ss_copy, sig) >= 0);
674
675 r = signalfd(d->fd, &ss_copy, SFD_NONBLOCK|SFD_CLOEXEC);
676 if (r < 0) {
677 r = -errno;
678 goto fail;
679 }
680
681 d->sigset = ss_copy;
f95387cd 682
9da4cb2b
LP
683 if (d->fd >= 0) {
684 if (ret)
685 *ret = d;
f95387cd 686 return 0;
9da4cb2b
LP
687 }
688
689 d->fd = r;
f95387cd
ZJS
690
691 ev.events = EPOLLIN;
9da4cb2b 692 ev.data.ptr = d;
f95387cd 693
9da4cb2b
LP
694 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, d->fd, &ev);
695 if (r < 0) {
696 r = -errno;
697 goto fail;
f95387cd
ZJS
698 }
699
9da4cb2b
LP
700 if (ret)
701 *ret = d;
702
f95387cd 703 return 0;
9da4cb2b
LP
704
705fail:
706 if (added) {
707 d->fd = safe_close(d->fd);
708 hashmap_remove(e->signal_data, &d->priority);
709 free(d);
710 }
711
712 return r;
713}
714
715static void event_unmask_signal_data(sd_event *e, struct signal_data *d, int sig) {
716 assert(e);
717 assert(d);
718
719 /* Turns off the specified signal in the signal data
720 * object. If the signal mask of the object becomes empty that
721 * way removes it. */
722
723 if (sigismember(&d->sigset, sig) == 0)
724 return;
725
726 assert_se(sigdelset(&d->sigset, sig) >= 0);
727
728 if (sigisemptyset(&d->sigset)) {
729
730 /* If all the mask is all-zero we can get rid of the structure */
731 hashmap_remove(e->signal_data, &d->priority);
732 assert(!d->current);
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);
15b38f93
LP
952 e->n_sources ++;
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
LP
1069 assert_return(usec != (uint64_t) -1, -EINVAL);
1070 assert_return(accuracy != (uint64_t) -1, -EINVAL);
da7e457c 1071 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1072 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 1073
c4f1aff2
TG
1074 if (!callback)
1075 callback = time_exit_callback;
1076
6a0f1f6d 1077 type = clock_to_event_source_type(clock);
15411c0c 1078 assert_return(type >= 0, -EOPNOTSUPP);
6a0f1f6d
LP
1079
1080 d = event_get_clock_data(e, type);
1081 assert(d);
c2ba3ad6 1082
c983e776
EV
1083 r = prioq_ensure_allocated(&d->earliest, earliest_time_prioq_compare);
1084 if (r < 0)
1085 return r;
fd38203a 1086
c983e776
EV
1087 r = prioq_ensure_allocated(&d->latest, latest_time_prioq_compare);
1088 if (r < 0)
1089 return r;
fd38203a 1090
6a0f1f6d
LP
1091 if (d->fd < 0) {
1092 r = event_setup_timer_fd(e, d, clock);
fd38203a
LP
1093 if (r < 0)
1094 return r;
1095 }
1096
a71fe8b8 1097 s = source_new(e, !ret, type);
fd38203a
LP
1098 if (!s)
1099 return -ENOMEM;
1100
1101 s->time.next = usec;
c2ba3ad6 1102 s->time.accuracy = accuracy == 0 ? DEFAULT_ACCURACY_USEC : accuracy;
fd38203a 1103 s->time.callback = callback;
da7e457c 1104 s->time.earliest_index = s->time.latest_index = PRIOQ_IDX_NULL;
fd38203a 1105 s->userdata = userdata;
baf76283 1106 s->enabled = SD_EVENT_ONESHOT;
fd38203a 1107
e07bbb7c
TG
1108 d->needs_rearm = true;
1109
6a0f1f6d 1110 r = prioq_put(d->earliest, s, &s->time.earliest_index);
c2ba3ad6
LP
1111 if (r < 0)
1112 goto fail;
1113
6a0f1f6d 1114 r = prioq_put(d->latest, s, &s->time.latest_index);
c2ba3ad6
LP
1115 if (r < 0)
1116 goto fail;
fd38203a 1117
a71fe8b8
LP
1118 if (ret)
1119 *ret = s;
1120
fd38203a 1121 return 0;
c2ba3ad6
LP
1122
1123fail:
1124 source_free(s);
1125 return r;
fd38203a
LP
1126}
1127
59bc1fd7
LP
1128static int signal_exit_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
1129 assert(s);
1130
1131 return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata));
1132}
1133
f7262a9f 1134_public_ int sd_event_add_signal(
305f78bf 1135 sd_event *e,
151b9b96 1136 sd_event_source **ret,
305f78bf 1137 int sig,
718db961 1138 sd_event_signal_handler_t callback,
151b9b96 1139 void *userdata) {
305f78bf 1140
fd38203a 1141 sd_event_source *s;
9da4cb2b 1142 struct signal_data *d;
3022d74b 1143 sigset_t ss;
fd38203a
LP
1144 int r;
1145
305f78bf
LP
1146 assert_return(e, -EINVAL);
1147 assert_return(sig > 0, -EINVAL);
1148 assert_return(sig < _NSIG, -EINVAL);
da7e457c 1149 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1150 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 1151
59bc1fd7
LP
1152 if (!callback)
1153 callback = signal_exit_callback;
1154
3022d74b 1155 r = pthread_sigmask(SIG_SETMASK, NULL, &ss);
50e0d56c
LP
1156 if (r != 0)
1157 return -r;
3022d74b
LP
1158
1159 if (!sigismember(&ss, sig))
1160 return -EBUSY;
1161
fd38203a
LP
1162 if (!e->signal_sources) {
1163 e->signal_sources = new0(sd_event_source*, _NSIG);
1164 if (!e->signal_sources)
1165 return -ENOMEM;
1166 } else if (e->signal_sources[sig])
1167 return -EBUSY;
1168
a71fe8b8 1169 s = source_new(e, !ret, SOURCE_SIGNAL);
fd38203a
LP
1170 if (!s)
1171 return -ENOMEM;
1172
1173 s->signal.sig = sig;
1174 s->signal.callback = callback;
1175 s->userdata = userdata;
baf76283 1176 s->enabled = SD_EVENT_ON;
fd38203a
LP
1177
1178 e->signal_sources[sig] = s;
fd38203a 1179
9da4cb2b
LP
1180 r = event_make_signal_data(e, sig, &d);
1181 if (r < 0) {
1182 source_free(s);
1183 return r;
fd38203a
LP
1184 }
1185
f1f00dbb
LP
1186 /* Use the signal name as description for the event source by default */
1187 (void) sd_event_source_set_description(s, signal_to_string(sig));
1188
a71fe8b8
LP
1189 if (ret)
1190 *ret = s;
1191
fd38203a
LP
1192 return 0;
1193}
1194
f7262a9f 1195_public_ int sd_event_add_child(
305f78bf 1196 sd_event *e,
151b9b96 1197 sd_event_source **ret,
305f78bf
LP
1198 pid_t pid,
1199 int options,
718db961 1200 sd_event_child_handler_t callback,
151b9b96 1201 void *userdata) {
305f78bf 1202
fd38203a
LP
1203 sd_event_source *s;
1204 int r;
1205
305f78bf
LP
1206 assert_return(e, -EINVAL);
1207 assert_return(pid > 1, -EINVAL);
1208 assert_return(!(options & ~(WEXITED|WSTOPPED|WCONTINUED)), -EINVAL);
1209 assert_return(options != 0, -EINVAL);
1210 assert_return(callback, -EINVAL);
da7e457c 1211 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1212 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 1213
d5099efc 1214 r = hashmap_ensure_allocated(&e->child_sources, NULL);
fd38203a
LP
1215 if (r < 0)
1216 return r;
1217
4a0b58c4 1218 if (hashmap_contains(e->child_sources, PID_TO_PTR(pid)))
fd38203a
LP
1219 return -EBUSY;
1220
a71fe8b8 1221 s = source_new(e, !ret, SOURCE_CHILD);
fd38203a
LP
1222 if (!s)
1223 return -ENOMEM;
1224
1225 s->child.pid = pid;
1226 s->child.options = options;
1227 s->child.callback = callback;
1228 s->userdata = userdata;
baf76283 1229 s->enabled = SD_EVENT_ONESHOT;
fd38203a 1230
4a0b58c4 1231 r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s);
fd38203a
LP
1232 if (r < 0) {
1233 source_free(s);
1234 return r;
1235 }
1236
baf76283 1237 e->n_enabled_child_sources ++;
fd38203a 1238
9da4cb2b
LP
1239 r = event_make_signal_data(e, SIGCHLD, NULL);
1240 if (r < 0) {
1241 e->n_enabled_child_sources--;
1242 source_free(s);
1243 return r;
fd38203a
LP
1244 }
1245
c2ba3ad6
LP
1246 e->need_process_child = true;
1247
a71fe8b8
LP
1248 if (ret)
1249 *ret = s;
1250
fd38203a
LP
1251 return 0;
1252}
1253
f7262a9f 1254_public_ int sd_event_add_defer(
305f78bf 1255 sd_event *e,
151b9b96 1256 sd_event_source **ret,
718db961 1257 sd_event_handler_t callback,
151b9b96 1258 void *userdata) {
305f78bf 1259
fd38203a
LP
1260 sd_event_source *s;
1261 int r;
1262
305f78bf
LP
1263 assert_return(e, -EINVAL);
1264 assert_return(callback, -EINVAL);
da7e457c 1265 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1266 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 1267
a71fe8b8 1268 s = source_new(e, !ret, SOURCE_DEFER);
fd38203a
LP
1269 if (!s)
1270 return -ENOMEM;
1271
1272 s->defer.callback = callback;
1273 s->userdata = userdata;
baf76283 1274 s->enabled = SD_EVENT_ONESHOT;
fd38203a
LP
1275
1276 r = source_set_pending(s, true);
1277 if (r < 0) {
1278 source_free(s);
1279 return r;
1280 }
1281
a71fe8b8
LP
1282 if (ret)
1283 *ret = s;
1284
fd38203a
LP
1285 return 0;
1286}
1287
6e9feda3
LP
1288_public_ int sd_event_add_post(
1289 sd_event *e,
1290 sd_event_source **ret,
1291 sd_event_handler_t callback,
1292 void *userdata) {
1293
1294 sd_event_source *s;
1295 int r;
1296
1297 assert_return(e, -EINVAL);
1298 assert_return(callback, -EINVAL);
6e9feda3
LP
1299 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
1300 assert_return(!event_pid_changed(e), -ECHILD);
1301
d5099efc 1302 r = set_ensure_allocated(&e->post_sources, NULL);
6e9feda3
LP
1303 if (r < 0)
1304 return r;
1305
a71fe8b8 1306 s = source_new(e, !ret, SOURCE_POST);
6e9feda3
LP
1307 if (!s)
1308 return -ENOMEM;
1309
1310 s->post.callback = callback;
1311 s->userdata = userdata;
1312 s->enabled = SD_EVENT_ON;
1313
1314 r = set_put(e->post_sources, s);
1315 if (r < 0) {
1316 source_free(s);
1317 return r;
1318 }
1319
a71fe8b8
LP
1320 if (ret)
1321 *ret = s;
1322
6e9feda3
LP
1323 return 0;
1324}
1325
6203e07a 1326_public_ int sd_event_add_exit(
305f78bf 1327 sd_event *e,
151b9b96 1328 sd_event_source **ret,
718db961 1329 sd_event_handler_t callback,
151b9b96 1330 void *userdata) {
305f78bf 1331
da7e457c
LP
1332 sd_event_source *s;
1333 int r;
1334
1335 assert_return(e, -EINVAL);
1336 assert_return(callback, -EINVAL);
1337 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
1338 assert_return(!event_pid_changed(e), -ECHILD);
1339
c983e776
EV
1340 r = prioq_ensure_allocated(&e->exit, exit_prioq_compare);
1341 if (r < 0)
1342 return r;
da7e457c 1343
a71fe8b8 1344 s = source_new(e, !ret, SOURCE_EXIT);
fd38203a 1345 if (!s)
da7e457c 1346 return -ENOMEM;
fd38203a 1347
6203e07a 1348 s->exit.callback = callback;
da7e457c 1349 s->userdata = userdata;
6203e07a 1350 s->exit.prioq_index = PRIOQ_IDX_NULL;
baf76283 1351 s->enabled = SD_EVENT_ONESHOT;
da7e457c 1352
6203e07a 1353 r = prioq_put(s->event->exit, s, &s->exit.prioq_index);
da7e457c
LP
1354 if (r < 0) {
1355 source_free(s);
1356 return r;
1357 }
1358
a71fe8b8
LP
1359 if (ret)
1360 *ret = s;
1361
da7e457c
LP
1362 return 0;
1363}
1364
f7262a9f 1365_public_ sd_event_source* sd_event_source_ref(sd_event_source *s) {
6680dd6b
LP
1366
1367 if (!s)
1368 return NULL;
da7e457c
LP
1369
1370 assert(s->n_ref >= 1);
1371 s->n_ref++;
fd38203a
LP
1372
1373 return s;
1374}
1375
f7262a9f 1376_public_ sd_event_source* sd_event_source_unref(sd_event_source *s) {
5b1bc83f
LP
1377
1378 if (!s)
1379 return NULL;
fd38203a 1380
da7e457c
LP
1381 assert(s->n_ref >= 1);
1382 s->n_ref--;
1383
12179984
LP
1384 if (s->n_ref <= 0) {
1385 /* Here's a special hack: when we are called from a
1386 * dispatch handler we won't free the event source
1387 * immediately, but we will detach the fd from the
1388 * epoll. This way it is safe for the caller to unref
1389 * the event source and immediately close the fd, but
1390 * we still retain a valid event source object after
1391 * the callback. */
1392
1393 if (s->dispatching) {
1394 if (s->type == SOURCE_IO)
1395 source_io_unregister(s);
a71fe8b8
LP
1396
1397 source_disconnect(s);
12179984
LP
1398 } else
1399 source_free(s);
1400 }
fd38203a
LP
1401
1402 return NULL;
1403}
1404
356779df 1405_public_ int sd_event_source_set_description(sd_event_source *s, const char *description) {
f7f53e9e 1406 assert_return(s, -EINVAL);
f4b2933e 1407 assert_return(!event_pid_changed(s->event), -ECHILD);
f7f53e9e 1408
356779df 1409 return free_and_strdup(&s->description, description);
f7f53e9e
TG
1410}
1411
356779df 1412_public_ int sd_event_source_get_description(sd_event_source *s, const char **description) {
f7f53e9e 1413 assert_return(s, -EINVAL);
356779df 1414 assert_return(description, -EINVAL);
f4b2933e
LP
1415 assert_return(s->description, -ENXIO);
1416 assert_return(!event_pid_changed(s->event), -ECHILD);
f7f53e9e 1417
356779df 1418 *description = s->description;
f7f53e9e
TG
1419 return 0;
1420}
1421
adcc4ca3 1422_public_ sd_event *sd_event_source_get_event(sd_event_source *s) {
305f78bf 1423 assert_return(s, NULL);
eaa3cbef
LP
1424
1425 return s->event;
1426}
1427
f7262a9f 1428_public_ int sd_event_source_get_pending(sd_event_source *s) {
305f78bf 1429 assert_return(s, -EINVAL);
6203e07a 1430 assert_return(s->type != SOURCE_EXIT, -EDOM);
da7e457c 1431 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1432 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1433
1434 return s->pending;
1435}
1436
f7262a9f 1437_public_ int sd_event_source_get_io_fd(sd_event_source *s) {
305f78bf
LP
1438 assert_return(s, -EINVAL);
1439 assert_return(s->type == SOURCE_IO, -EDOM);
1440 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1441
1442 return s->io.fd;
1443}
1444
30caf8f3
LP
1445_public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) {
1446 int r;
1447
1448 assert_return(s, -EINVAL);
8ac43fee 1449 assert_return(fd >= 0, -EBADF);
30caf8f3
LP
1450 assert_return(s->type == SOURCE_IO, -EDOM);
1451 assert_return(!event_pid_changed(s->event), -ECHILD);
1452
1453 if (s->io.fd == fd)
1454 return 0;
1455
1456 if (s->enabled == SD_EVENT_OFF) {
1457 s->io.fd = fd;
1458 s->io.registered = false;
1459 } else {
1460 int saved_fd;
1461
1462 saved_fd = s->io.fd;
1463 assert(s->io.registered);
1464
1465 s->io.fd = fd;
1466 s->io.registered = false;
1467
1468 r = source_io_register(s, s->enabled, s->io.events);
1469 if (r < 0) {
1470 s->io.fd = saved_fd;
1471 s->io.registered = true;
1472 return r;
1473 }
1474
1475 epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, saved_fd, NULL);
1476 }
1477
1478 return 0;
1479}
1480
f7262a9f 1481_public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) {
305f78bf
LP
1482 assert_return(s, -EINVAL);
1483 assert_return(events, -EINVAL);
1484 assert_return(s->type == SOURCE_IO, -EDOM);
1485 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1486
1487 *events = s->io.events;
1488 return 0;
1489}
1490
f7262a9f 1491_public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) {
fd38203a
LP
1492 int r;
1493
305f78bf
LP
1494 assert_return(s, -EINVAL);
1495 assert_return(s->type == SOURCE_IO, -EDOM);
2a16a986 1496 assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL);
da7e457c 1497 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1498 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a 1499
b63c8d4f
DH
1500 /* edge-triggered updates are never skipped, so we can reset edges */
1501 if (s->io.events == events && !(events & EPOLLET))
fd38203a
LP
1502 return 0;
1503
baf76283 1504 if (s->enabled != SD_EVENT_OFF) {
e4715127 1505 r = source_io_register(s, s->enabled, events);
fd38203a
LP
1506 if (r < 0)
1507 return r;
1508 }
1509
1510 s->io.events = events;
503f39c3 1511 source_set_pending(s, false);
fd38203a
LP
1512
1513 return 0;
1514}
1515
f7262a9f 1516_public_ int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents) {
305f78bf
LP
1517 assert_return(s, -EINVAL);
1518 assert_return(revents, -EINVAL);
1519 assert_return(s->type == SOURCE_IO, -EDOM);
1520 assert_return(s->pending, -ENODATA);
1521 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1522
1523 *revents = s->io.revents;
1524 return 0;
1525}
1526
f7262a9f 1527_public_ int sd_event_source_get_signal(sd_event_source *s) {
305f78bf
LP
1528 assert_return(s, -EINVAL);
1529 assert_return(s->type == SOURCE_SIGNAL, -EDOM);
1530 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1531
1532 return s->signal.sig;
1533}
1534
31927c16 1535_public_ int sd_event_source_get_priority(sd_event_source *s, int64_t *priority) {
305f78bf
LP
1536 assert_return(s, -EINVAL);
1537 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1538
1539 return s->priority;
1540}
1541
31927c16 1542_public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) {
9da4cb2b
LP
1543 int r;
1544
305f78bf 1545 assert_return(s, -EINVAL);
da7e457c 1546 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1547 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1548
1549 if (s->priority == priority)
1550 return 0;
1551
9da4cb2b
LP
1552 if (s->type == SOURCE_SIGNAL && s->enabled != SD_EVENT_OFF) {
1553 struct signal_data *old, *d;
1554
1555 /* Move us from the signalfd belonging to the old
1556 * priority to the signalfd of the new priority */
1557
1558 assert_se(old = hashmap_get(s->event->signal_data, &s->priority));
1559
1560 s->priority = priority;
1561
1562 r = event_make_signal_data(s->event, s->signal.sig, &d);
1563 if (r < 0) {
1564 s->priority = old->priority;
1565 return r;
1566 }
1567
1568 event_unmask_signal_data(s->event, old, s->signal.sig);
1569 } else
1570 s->priority = priority;
fd38203a
LP
1571
1572 if (s->pending)
c2ba3ad6 1573 prioq_reshuffle(s->event->pending, s, &s->pending_index);
fd38203a
LP
1574
1575 if (s->prepare)
c2ba3ad6 1576 prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
fd38203a 1577
6203e07a
LP
1578 if (s->type == SOURCE_EXIT)
1579 prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
305f78bf 1580
fd38203a
LP
1581 return 0;
1582}
1583
f7262a9f 1584_public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) {
305f78bf
LP
1585 assert_return(s, -EINVAL);
1586 assert_return(m, -EINVAL);
1587 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a 1588
baf76283 1589 *m = s->enabled;
fd38203a
LP
1590 return 0;
1591}
1592
f7262a9f 1593_public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
fd38203a
LP
1594 int r;
1595
305f78bf
LP
1596 assert_return(s, -EINVAL);
1597 assert_return(m == SD_EVENT_OFF || m == SD_EVENT_ON || m == SD_EVENT_ONESHOT, -EINVAL);
305f78bf 1598 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a 1599
cc567911
LP
1600 /* If we are dead anyway, we are fine with turning off
1601 * sources, but everything else needs to fail. */
1602 if (s->event->state == SD_EVENT_FINISHED)
1603 return m == SD_EVENT_OFF ? 0 : -ESTALE;
1604
baf76283 1605 if (s->enabled == m)
fd38203a
LP
1606 return 0;
1607
baf76283 1608 if (m == SD_EVENT_OFF) {
fd38203a
LP
1609
1610 switch (s->type) {
1611
1612 case SOURCE_IO:
366e6411 1613 source_io_unregister(s);
baf76283 1614 s->enabled = m;
fd38203a
LP
1615 break;
1616
6a0f1f6d 1617 case SOURCE_TIME_REALTIME:
a8548816 1618 case SOURCE_TIME_BOOTTIME:
6a0f1f6d
LP
1619 case SOURCE_TIME_MONOTONIC:
1620 case SOURCE_TIME_REALTIME_ALARM:
1621 case SOURCE_TIME_BOOTTIME_ALARM: {
1622 struct clock_data *d;
fd38203a 1623
baf76283 1624 s->enabled = m;
6a0f1f6d
LP
1625 d = event_get_clock_data(s->event, s->type);
1626 assert(d);
1627
1628 prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
1629 prioq_reshuffle(d->latest, s, &s->time.latest_index);
212bbb17 1630 d->needs_rearm = true;
fd38203a 1631 break;
6a0f1f6d 1632 }
fd38203a
LP
1633
1634 case SOURCE_SIGNAL:
baf76283 1635 s->enabled = m;
4807d2d0 1636
9da4cb2b 1637 event_gc_signal_data(s->event, &s->priority, s->signal.sig);
fd38203a
LP
1638 break;
1639
1640 case SOURCE_CHILD:
baf76283 1641 s->enabled = m;
fd38203a 1642
baf76283
LP
1643 assert(s->event->n_enabled_child_sources > 0);
1644 s->event->n_enabled_child_sources--;
fd38203a 1645
9da4cb2b 1646 event_gc_signal_data(s->event, &s->priority, SIGCHLD);
fd38203a
LP
1647 break;
1648
6203e07a 1649 case SOURCE_EXIT:
305f78bf 1650 s->enabled = m;
6203e07a 1651 prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
305f78bf
LP
1652 break;
1653
1654 case SOURCE_DEFER:
6e9feda3 1655 case SOURCE_POST:
baf76283 1656 s->enabled = m;
fd38203a 1657 break;
9d3e3aa5 1658
6a0f1f6d 1659 default:
9d3e3aa5 1660 assert_not_reached("Wut? I shouldn't exist.");
fd38203a
LP
1661 }
1662
1663 } else {
1664 switch (s->type) {
1665
1666 case SOURCE_IO:
1667 r = source_io_register(s, m, s->io.events);
1668 if (r < 0)
1669 return r;
1670
baf76283 1671 s->enabled = m;
fd38203a
LP
1672 break;
1673
6a0f1f6d 1674 case SOURCE_TIME_REALTIME:
a8548816 1675 case SOURCE_TIME_BOOTTIME:
6a0f1f6d
LP
1676 case SOURCE_TIME_MONOTONIC:
1677 case SOURCE_TIME_REALTIME_ALARM:
1678 case SOURCE_TIME_BOOTTIME_ALARM: {
1679 struct clock_data *d;
fd38203a 1680
baf76283 1681 s->enabled = m;
6a0f1f6d
LP
1682 d = event_get_clock_data(s->event, s->type);
1683 assert(d);
1684
1685 prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
1686 prioq_reshuffle(d->latest, s, &s->time.latest_index);
212bbb17 1687 d->needs_rearm = true;
fd38203a 1688 break;
6a0f1f6d 1689 }
fd38203a
LP
1690
1691 case SOURCE_SIGNAL:
4807d2d0
ZJS
1692
1693 s->enabled = m;
9da4cb2b
LP
1694
1695 r = event_make_signal_data(s->event, s->signal.sig, NULL);
1696 if (r < 0) {
1697 s->enabled = SD_EVENT_OFF;
1698 event_gc_signal_data(s->event, &s->priority, s->signal.sig);
1699 return r;
1700 }
1701
fd38203a
LP
1702 break;
1703
1704 case SOURCE_CHILD:
4807d2d0 1705
9da4cb2b 1706 if (s->enabled == SD_EVENT_OFF)
4807d2d0 1707 s->event->n_enabled_child_sources++;
7a0d4a3d
DH
1708
1709 s->enabled = m;
9da4cb2b 1710
10edebf6 1711 r = event_make_signal_data(s->event, SIGCHLD, NULL);
9da4cb2b
LP
1712 if (r < 0) {
1713 s->enabled = SD_EVENT_OFF;
1714 s->event->n_enabled_child_sources--;
1715 event_gc_signal_data(s->event, &s->priority, SIGCHLD);
1716 return r;
1717 }
1718
fd38203a
LP
1719 break;
1720
6203e07a 1721 case SOURCE_EXIT:
305f78bf 1722 s->enabled = m;
6203e07a 1723 prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
305f78bf
LP
1724 break;
1725
1726 case SOURCE_DEFER:
6e9feda3 1727 case SOURCE_POST:
baf76283 1728 s->enabled = m;
fd38203a 1729 break;
9d3e3aa5 1730
6a0f1f6d 1731 default:
9d3e3aa5 1732 assert_not_reached("Wut? I shouldn't exist.");
fd38203a
LP
1733 }
1734 }
1735
1736 if (s->pending)
1737 prioq_reshuffle(s->event->pending, s, &s->pending_index);
1738
1739 if (s->prepare)
1740 prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
1741
1742 return 0;
1743}
1744
f7262a9f 1745_public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
305f78bf
LP
1746 assert_return(s, -EINVAL);
1747 assert_return(usec, -EINVAL);
6a0f1f6d 1748 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
305f78bf 1749 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1750
1751 *usec = s->time.next;
1752 return 0;
1753}
1754
f7262a9f 1755_public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
6a0f1f6d
LP
1756 struct clock_data *d;
1757
305f78bf
LP
1758 assert_return(s, -EINVAL);
1759 assert_return(usec != (uint64_t) -1, -EINVAL);
6a0f1f6d 1760 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
da7e457c 1761 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1762 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a 1763
fd38203a 1764 s->time.next = usec;
2576a19e 1765
0cc1125a 1766 source_set_pending(s, false);
fd38203a 1767
6a0f1f6d
LP
1768 d = event_get_clock_data(s->event, s->type);
1769 assert(d);
1770
1771 prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
1772 prioq_reshuffle(d->latest, s, &s->time.latest_index);
212bbb17 1773 d->needs_rearm = true;
fd38203a
LP
1774
1775 return 0;
1776}
1777
f7262a9f 1778_public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) {
305f78bf
LP
1779 assert_return(s, -EINVAL);
1780 assert_return(usec, -EINVAL);
6a0f1f6d 1781 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
305f78bf
LP
1782 assert_return(!event_pid_changed(s->event), -ECHILD);
1783
1784 *usec = s->time.accuracy;
1785 return 0;
1786}
1787
f7262a9f 1788_public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) {
6a0f1f6d
LP
1789 struct clock_data *d;
1790
305f78bf
LP
1791 assert_return(s, -EINVAL);
1792 assert_return(usec != (uint64_t) -1, -EINVAL);
6a0f1f6d 1793 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
da7e457c 1794 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1795 assert_return(!event_pid_changed(s->event), -ECHILD);
eaa3cbef
LP
1796
1797 if (usec == 0)
1798 usec = DEFAULT_ACCURACY_USEC;
1799
eaa3cbef
LP
1800 s->time.accuracy = usec;
1801
2576a19e
LP
1802 source_set_pending(s, false);
1803
6a0f1f6d
LP
1804 d = event_get_clock_data(s->event, s->type);
1805 assert(d);
1806
1807 prioq_reshuffle(d->latest, s, &s->time.latest_index);
212bbb17 1808 d->needs_rearm = true;
6a0f1f6d
LP
1809
1810 return 0;
1811}
1812
1813_public_ int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock) {
1814 assert_return(s, -EINVAL);
1815 assert_return(clock, -EINVAL);
1816 assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
1817 assert_return(!event_pid_changed(s->event), -ECHILD);
eaa3cbef 1818
6a0f1f6d 1819 *clock = event_source_type_to_clock(s->type);
eaa3cbef
LP
1820 return 0;
1821}
1822
f7262a9f 1823_public_ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) {
4bee8012
LP
1824 assert_return(s, -EINVAL);
1825 assert_return(pid, -EINVAL);
1826 assert_return(s->type == SOURCE_CHILD, -EDOM);
1827 assert_return(!event_pid_changed(s->event), -ECHILD);
1828
1829 *pid = s->child.pid;
1830 return 0;
1831}
1832
718db961 1833_public_ int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback) {
fd38203a
LP
1834 int r;
1835
da7e457c 1836 assert_return(s, -EINVAL);
6203e07a 1837 assert_return(s->type != SOURCE_EXIT, -EDOM);
da7e457c
LP
1838 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
1839 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1840
1841 if (s->prepare == callback)
1842 return 0;
1843
1844 if (callback && s->prepare) {
1845 s->prepare = callback;
1846 return 0;
1847 }
1848
1849 r = prioq_ensure_allocated(&s->event->prepare, prepare_prioq_compare);
1850 if (r < 0)
1851 return r;
1852
1853 s->prepare = callback;
1854
1855 if (callback) {
1856 r = prioq_put(s->event->prepare, s, &s->prepare_index);
1857 if (r < 0)
1858 return r;
1859 } else
1860 prioq_remove(s->event->prepare, s, &s->prepare_index);
1861
1862 return 0;
1863}
1864
f7262a9f 1865_public_ void* sd_event_source_get_userdata(sd_event_source *s) {
da7e457c 1866 assert_return(s, NULL);
fd38203a
LP
1867
1868 return s->userdata;
1869}
1870
8f726607
LP
1871_public_ void *sd_event_source_set_userdata(sd_event_source *s, void *userdata) {
1872 void *ret;
1873
1874 assert_return(s, NULL);
1875
1876 ret = s->userdata;
1877 s->userdata = userdata;
1878
1879 return ret;
1880}
1881
c2ba3ad6
LP
1882static usec_t sleep_between(sd_event *e, usec_t a, usec_t b) {
1883 usec_t c;
1884 assert(e);
1885 assert(a <= b);
1886
1887 if (a <= 0)
1888 return 0;
1889
1890 if (b <= a + 1)
1891 return a;
1892
52444dc4
LP
1893 initialize_perturb(e);
1894
c2ba3ad6
LP
1895 /*
1896 Find a good time to wake up again between times a and b. We
1897 have two goals here:
1898
1899 a) We want to wake up as seldom as possible, hence prefer
1900 later times over earlier times.
1901
1902 b) But if we have to wake up, then let's make sure to
1903 dispatch as much as possible on the entire system.
1904
1905 We implement this by waking up everywhere at the same time
850516e0 1906 within any given minute if we can, synchronised via the
c2ba3ad6 1907 perturbation value determined from the boot ID. If we can't,
ba276c81
LP
1908 then we try to find the same spot in every 10s, then 1s and
1909 then 250ms step. Otherwise, we pick the last possible time
1910 to wake up.
c2ba3ad6
LP
1911 */
1912
850516e0
LP
1913 c = (b / USEC_PER_MINUTE) * USEC_PER_MINUTE + e->perturb;
1914 if (c >= b) {
1915 if (_unlikely_(c < USEC_PER_MINUTE))
1916 return b;
1917
1918 c -= USEC_PER_MINUTE;
1919 }
1920
ba276c81
LP
1921 if (c >= a)
1922 return c;
1923
1924 c = (b / (USEC_PER_SEC*10)) * (USEC_PER_SEC*10) + (e->perturb % (USEC_PER_SEC*10));
1925 if (c >= b) {
1926 if (_unlikely_(c < USEC_PER_SEC*10))
1927 return b;
1928
1929 c -= USEC_PER_SEC*10;
1930 }
1931
850516e0
LP
1932 if (c >= a)
1933 return c;
1934
1935 c = (b / USEC_PER_SEC) * USEC_PER_SEC + (e->perturb % USEC_PER_SEC);
c2ba3ad6
LP
1936 if (c >= b) {
1937 if (_unlikely_(c < USEC_PER_SEC))
1938 return b;
1939
1940 c -= USEC_PER_SEC;
1941 }
1942
1943 if (c >= a)
1944 return c;
1945
1946 c = (b / (USEC_PER_MSEC*250)) * (USEC_PER_MSEC*250) + (e->perturb % (USEC_PER_MSEC*250));
1947 if (c >= b) {
1948 if (_unlikely_(c < USEC_PER_MSEC*250))
1949 return b;
1950
1951 c -= USEC_PER_MSEC*250;
1952 }
1953
1954 if (c >= a)
1955 return c;
1956
1957 return b;
1958}
1959
fd38203a
LP
1960static int event_arm_timer(
1961 sd_event *e,
6a0f1f6d 1962 struct clock_data *d) {
fd38203a
LP
1963
1964 struct itimerspec its = {};
c2ba3ad6
LP
1965 sd_event_source *a, *b;
1966 usec_t t;
fd38203a
LP
1967 int r;
1968
cde93897 1969 assert(e);
6a0f1f6d 1970 assert(d);
fd38203a 1971
d06441da 1972 if (!d->needs_rearm)
212bbb17
TG
1973 return 0;
1974 else
1975 d->needs_rearm = false;
1976
6a0f1f6d 1977 a = prioq_peek(d->earliest);
72aedc1e
LP
1978 if (!a || a->enabled == SD_EVENT_OFF) {
1979
6a0f1f6d 1980 if (d->fd < 0)
c57b5ca3
LP
1981 return 0;
1982
3a43da28 1983 if (d->next == USEC_INFINITY)
72aedc1e
LP
1984 return 0;
1985
1986 /* disarm */
6a0f1f6d 1987 r = timerfd_settime(d->fd, TFD_TIMER_ABSTIME, &its, NULL);
72aedc1e
LP
1988 if (r < 0)
1989 return r;
1990
3a43da28 1991 d->next = USEC_INFINITY;
fd38203a 1992 return 0;
72aedc1e 1993 }
fd38203a 1994
6a0f1f6d 1995 b = prioq_peek(d->latest);
baf76283 1996 assert_se(b && b->enabled != SD_EVENT_OFF);
c2ba3ad6
LP
1997
1998 t = sleep_between(e, a->time.next, b->time.next + b->time.accuracy);
6a0f1f6d 1999 if (d->next == t)
fd38203a
LP
2000 return 0;
2001
6a0f1f6d 2002 assert_se(d->fd >= 0);
fd38203a 2003
c2ba3ad6 2004 if (t == 0) {
fd38203a
LP
2005 /* We don' want to disarm here, just mean some time looooong ago. */
2006 its.it_value.tv_sec = 0;
2007 its.it_value.tv_nsec = 1;
2008 } else
c2ba3ad6 2009 timespec_store(&its.it_value, t);
fd38203a 2010
6a0f1f6d 2011 r = timerfd_settime(d->fd, TFD_TIMER_ABSTIME, &its, NULL);
fd38203a 2012 if (r < 0)
cde93897 2013 return -errno;
fd38203a 2014
6a0f1f6d 2015 d->next = t;
fd38203a
LP
2016 return 0;
2017}
2018
9a800b56 2019static int process_io(sd_event *e, sd_event_source *s, uint32_t revents) {
fd38203a
LP
2020 assert(e);
2021 assert(s);
2022 assert(s->type == SOURCE_IO);
2023
9a800b56
LP
2024 /* If the event source was already pending, we just OR in the
2025 * new revents, otherwise we reset the value. The ORing is
2026 * necessary to handle EPOLLONESHOT events properly where
2027 * readability might happen independently of writability, and
2028 * we need to keep track of both */
2029
2030 if (s->pending)
2031 s->io.revents |= revents;
2032 else
2033 s->io.revents = revents;
fd38203a 2034
fd38203a
LP
2035 return source_set_pending(s, true);
2036}
2037
72aedc1e 2038static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) {
fd38203a
LP
2039 uint64_t x;
2040 ssize_t ss;
2041
2042 assert(e);
da7e457c 2043 assert(fd >= 0);
72aedc1e 2044
305f78bf 2045 assert_return(events == EPOLLIN, -EIO);
fd38203a
LP
2046
2047 ss = read(fd, &x, sizeof(x));
2048 if (ss < 0) {
2049 if (errno == EAGAIN || errno == EINTR)
2050 return 0;
2051
2052 return -errno;
2053 }
2054
8d35dae7 2055 if (_unlikely_(ss != sizeof(x)))
fd38203a
LP
2056 return -EIO;
2057
cde93897 2058 if (next)
3a43da28 2059 *next = USEC_INFINITY;
72aedc1e 2060
fd38203a
LP
2061 return 0;
2062}
2063
305f78bf
LP
2064static int process_timer(
2065 sd_event *e,
2066 usec_t n,
6a0f1f6d 2067 struct clock_data *d) {
305f78bf 2068
fd38203a
LP
2069 sd_event_source *s;
2070 int r;
2071
2072 assert(e);
6a0f1f6d 2073 assert(d);
fd38203a
LP
2074
2075 for (;;) {
6a0f1f6d 2076 s = prioq_peek(d->earliest);
fd38203a
LP
2077 if (!s ||
2078 s->time.next > n ||
baf76283 2079 s->enabled == SD_EVENT_OFF ||
fd38203a
LP
2080 s->pending)
2081 break;
2082
2083 r = source_set_pending(s, true);
2084 if (r < 0)
2085 return r;
2086
6a0f1f6d
LP
2087 prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
2088 prioq_reshuffle(d->latest, s, &s->time.latest_index);
e07bbb7c 2089 d->needs_rearm = true;
fd38203a
LP
2090 }
2091
2092 return 0;
2093}
2094
2095static int process_child(sd_event *e) {
2096 sd_event_source *s;
2097 Iterator i;
2098 int r;
2099
2100 assert(e);
2101
c2ba3ad6
LP
2102 e->need_process_child = false;
2103
fd38203a
LP
2104 /*
2105 So, this is ugly. We iteratively invoke waitid() with P_PID
2106 + WNOHANG for each PID we wait for, instead of using
2107 P_ALL. This is because we only want to get child
2108 information of very specific child processes, and not all
2109 of them. We might not have processed the SIGCHLD even of a
2110 previous invocation and we don't want to maintain a
2111 unbounded *per-child* event queue, hence we really don't
2112 want anything flushed out of the kernel's queue that we
2113 don't care about. Since this is O(n) this means that if you
2114 have a lot of processes you probably want to handle SIGCHLD
2115 yourself.
08cd1552
LP
2116
2117 We do not reap the children here (by using WNOWAIT), this
2118 is only done after the event source is dispatched so that
2119 the callback still sees the process as a zombie.
fd38203a
LP
2120 */
2121
2122 HASHMAP_FOREACH(s, e->child_sources, i) {
2123 assert(s->type == SOURCE_CHILD);
2124
2125 if (s->pending)
2126 continue;
2127
baf76283 2128 if (s->enabled == SD_EVENT_OFF)
fd38203a
LP
2129 continue;
2130
2131 zero(s->child.siginfo);
08cd1552
LP
2132 r = waitid(P_PID, s->child.pid, &s->child.siginfo,
2133 WNOHANG | (s->child.options & WEXITED ? WNOWAIT : 0) | s->child.options);
fd38203a
LP
2134 if (r < 0)
2135 return -errno;
2136
2137 if (s->child.siginfo.si_pid != 0) {
08cd1552
LP
2138 bool zombie =
2139 s->child.siginfo.si_code == CLD_EXITED ||
2140 s->child.siginfo.si_code == CLD_KILLED ||
2141 s->child.siginfo.si_code == CLD_DUMPED;
2142
2143 if (!zombie && (s->child.options & WEXITED)) {
2144 /* If the child isn't dead then let's
2145 * immediately remove the state change
2146 * from the queue, since there's no
2147 * benefit in leaving it queued */
2148
2149 assert(s->child.options & (WSTOPPED|WCONTINUED));
2150 waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|(s->child.options & (WSTOPPED|WCONTINUED)));
2151 }
2152
fd38203a
LP
2153 r = source_set_pending(s, true);
2154 if (r < 0)
2155 return r;
2156 }
2157 }
2158
fd38203a
LP
2159 return 0;
2160}
2161
9da4cb2b 2162static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
fd38203a 2163 bool read_one = false;
fd38203a
LP
2164 int r;
2165
da7e457c 2166 assert(e);
305f78bf 2167 assert_return(events == EPOLLIN, -EIO);
fd38203a 2168
9da4cb2b
LP
2169 /* If there's a signal queued on this priority and SIGCHLD is
2170 on this priority too, then make sure to recheck the
2171 children we watch. This is because we only ever dequeue
2172 the first signal per priority, and if we dequeue one, and
2173 SIGCHLD might be enqueued later we wouldn't know, but we
2174 might have higher priority children we care about hence we
2175 need to check that explicitly. */
2176
2177 if (sigismember(&d->sigset, SIGCHLD))
2178 e->need_process_child = true;
2179
2180 /* If there's already an event source pending for this
2181 * priority we don't read another */
2182 if (d->current)
2183 return 0;
2184
fd38203a 2185 for (;;) {
0eb2e0e3 2186 struct signalfd_siginfo si;
7057bd99 2187 ssize_t n;
92daebc0 2188 sd_event_source *s = NULL;
fd38203a 2189
9da4cb2b 2190 n = read(d->fd, &si, sizeof(si));
7057bd99 2191 if (n < 0) {
fd38203a
LP
2192 if (errno == EAGAIN || errno == EINTR)
2193 return read_one;
2194
2195 return -errno;
2196 }
2197
7057bd99 2198 if (_unlikely_(n != sizeof(si)))
fd38203a
LP
2199 return -EIO;
2200
7057bd99
ZJS
2201 assert(si.ssi_signo < _NSIG);
2202
fd38203a
LP
2203 read_one = true;
2204
92daebc0
LP
2205 if (e->signal_sources)
2206 s = e->signal_sources[si.ssi_signo];
92daebc0
LP
2207 if (!s)
2208 continue;
9da4cb2b
LP
2209 if (s->pending)
2210 continue;
fd38203a
LP
2211
2212 s->signal.siginfo = si;
9da4cb2b
LP
2213 d->current = s;
2214
fd38203a
LP
2215 r = source_set_pending(s, true);
2216 if (r < 0)
2217 return r;
9da4cb2b
LP
2218
2219 return 1;
fd38203a 2220 }
fd38203a
LP
2221}
2222
2223static int source_dispatch(sd_event_source *s) {
fe8245eb 2224 int r = 0;
fd38203a
LP
2225
2226 assert(s);
6203e07a 2227 assert(s->pending || s->type == SOURCE_EXIT);
fd38203a 2228
6203e07a 2229 if (s->type != SOURCE_DEFER && s->type != SOURCE_EXIT) {
da7e457c
LP
2230 r = source_set_pending(s, false);
2231 if (r < 0)
2232 return r;
2233 }
fd38203a 2234
6e9feda3
LP
2235 if (s->type != SOURCE_POST) {
2236 sd_event_source *z;
2237 Iterator i;
2238
2239 /* If we execute a non-post source, let's mark all
2240 * post sources as pending */
2241
2242 SET_FOREACH(z, s->event->post_sources, i) {
2243 if (z->enabled == SD_EVENT_OFF)
2244 continue;
2245
2246 r = source_set_pending(z, true);
2247 if (r < 0)
2248 return r;
2249 }
2250 }
2251
baf76283
LP
2252 if (s->enabled == SD_EVENT_ONESHOT) {
2253 r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
fd38203a
LP
2254 if (r < 0)
2255 return r;
2256 }
2257
12179984 2258 s->dispatching = true;
b7484e2a 2259
fd38203a
LP
2260 switch (s->type) {
2261
2262 case SOURCE_IO:
2263 r = s->io.callback(s, s->io.fd, s->io.revents, s->userdata);
2264 break;
2265
6a0f1f6d 2266 case SOURCE_TIME_REALTIME:
a8548816 2267 case SOURCE_TIME_BOOTTIME:
6a0f1f6d
LP
2268 case SOURCE_TIME_MONOTONIC:
2269 case SOURCE_TIME_REALTIME_ALARM:
2270 case SOURCE_TIME_BOOTTIME_ALARM:
fd38203a
LP
2271 r = s->time.callback(s, s->time.next, s->userdata);
2272 break;
2273
2274 case SOURCE_SIGNAL:
2275 r = s->signal.callback(s, &s->signal.siginfo, s->userdata);
2276 break;
2277
08cd1552
LP
2278 case SOURCE_CHILD: {
2279 bool zombie;
2280
2281 zombie = s->child.siginfo.si_code == CLD_EXITED ||
2282 s->child.siginfo.si_code == CLD_KILLED ||
2283 s->child.siginfo.si_code == CLD_DUMPED;
2284
fd38203a 2285 r = s->child.callback(s, &s->child.siginfo, s->userdata);
08cd1552
LP
2286
2287 /* Now, reap the PID for good. */
2288 if (zombie)
2289 waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|WEXITED);
2290
fd38203a 2291 break;
08cd1552 2292 }
fd38203a
LP
2293
2294 case SOURCE_DEFER:
2295 r = s->defer.callback(s, s->userdata);
2296 break;
da7e457c 2297
6e9feda3
LP
2298 case SOURCE_POST:
2299 r = s->post.callback(s, s->userdata);
2300 break;
2301
6203e07a
LP
2302 case SOURCE_EXIT:
2303 r = s->exit.callback(s, s->userdata);
da7e457c 2304 break;
9d3e3aa5
LP
2305
2306 case SOURCE_WATCHDOG:
a71fe8b8 2307 case _SOURCE_EVENT_SOURCE_TYPE_MAX:
9f2a50a3 2308 case _SOURCE_EVENT_SOURCE_TYPE_INVALID:
9d3e3aa5 2309 assert_not_reached("Wut? I shouldn't exist.");
fd38203a
LP
2310 }
2311
12179984
LP
2312 s->dispatching = false;
2313
55cbfaa5
DM
2314 if (r < 0)
2315 log_debug_errno(r, "Event source %s (type %s) returned error, disabling: %m",
2316 strna(s->description), event_source_type_to_string(s->type));
12179984
LP
2317
2318 if (s->n_ref == 0)
2319 source_free(s);
2320 else if (r < 0)
6203e07a 2321 sd_event_source_set_enabled(s, SD_EVENT_OFF);
b7484e2a 2322
6203e07a 2323 return 1;
fd38203a
LP
2324}
2325
2326static int event_prepare(sd_event *e) {
2327 int r;
2328
2329 assert(e);
2330
2331 for (;;) {
2332 sd_event_source *s;
2333
2334 s = prioq_peek(e->prepare);
baf76283 2335 if (!s || s->prepare_iteration == e->iteration || s->enabled == SD_EVENT_OFF)
fd38203a
LP
2336 break;
2337
2338 s->prepare_iteration = e->iteration;
2339 r = prioq_reshuffle(e->prepare, s, &s->prepare_index);
2340 if (r < 0)
2341 return r;
2342
2343 assert(s->prepare);
12179984
LP
2344
2345 s->dispatching = true;
fd38203a 2346 r = s->prepare(s, s->userdata);
12179984
LP
2347 s->dispatching = false;
2348
55cbfaa5
DM
2349 if (r < 0)
2350 log_debug_errno(r, "Prepare callback of event source %s (type %s) returned error, disabling: %m",
2351 strna(s->description), event_source_type_to_string(s->type));
fd38203a 2352
12179984
LP
2353 if (s->n_ref == 0)
2354 source_free(s);
2355 else if (r < 0)
2356 sd_event_source_set_enabled(s, SD_EVENT_OFF);
fd38203a
LP
2357 }
2358
2359 return 0;
2360}
2361
6203e07a 2362static int dispatch_exit(sd_event *e) {
da7e457c
LP
2363 sd_event_source *p;
2364 int r;
2365
2366 assert(e);
2367
6203e07a 2368 p = prioq_peek(e->exit);
baf76283 2369 if (!p || p->enabled == SD_EVENT_OFF) {
da7e457c
LP
2370 e->state = SD_EVENT_FINISHED;
2371 return 0;
2372 }
2373
2374 sd_event_ref(e);
2375 e->iteration++;
6203e07a 2376 e->state = SD_EVENT_EXITING;
da7e457c
LP
2377
2378 r = source_dispatch(p);
2379
2b0c9ef7 2380 e->state = SD_EVENT_INITIAL;
da7e457c
LP
2381 sd_event_unref(e);
2382
2383 return r;
2384}
2385
c2ba3ad6
LP
2386static sd_event_source* event_next_pending(sd_event *e) {
2387 sd_event_source *p;
2388
da7e457c
LP
2389 assert(e);
2390
c2ba3ad6
LP
2391 p = prioq_peek(e->pending);
2392 if (!p)
2393 return NULL;
2394
baf76283 2395 if (p->enabled == SD_EVENT_OFF)
c2ba3ad6
LP
2396 return NULL;
2397
2398 return p;
2399}
2400
cde93897
LP
2401static int arm_watchdog(sd_event *e) {
2402 struct itimerspec its = {};
2403 usec_t t;
2404 int r;
2405
2406 assert(e);
2407 assert(e->watchdog_fd >= 0);
2408
2409 t = sleep_between(e,
2410 e->watchdog_last + (e->watchdog_period / 2),
2411 e->watchdog_last + (e->watchdog_period * 3 / 4));
2412
2413 timespec_store(&its.it_value, t);
2414
75145780
LP
2415 /* Make sure we never set the watchdog to 0, which tells the
2416 * kernel to disable it. */
2417 if (its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0)
2418 its.it_value.tv_nsec = 1;
2419
cde93897
LP
2420 r = timerfd_settime(e->watchdog_fd, TFD_TIMER_ABSTIME, &its, NULL);
2421 if (r < 0)
2422 return -errno;
2423
2424 return 0;
2425}
2426
2427static int process_watchdog(sd_event *e) {
2428 assert(e);
2429
2430 if (!e->watchdog)
2431 return 0;
2432
2433 /* Don't notify watchdog too often */
2434 if (e->watchdog_last + e->watchdog_period / 4 > e->timestamp.monotonic)
2435 return 0;
2436
2437 sd_notify(false, "WATCHDOG=1");
2438 e->watchdog_last = e->timestamp.monotonic;
2439
2440 return arm_watchdog(e);
2441}
2442
c45a5a74
TG
2443_public_ int sd_event_prepare(sd_event *e) {
2444 int r;
fd38203a 2445
da7e457c
LP
2446 assert_return(e, -EINVAL);
2447 assert_return(!event_pid_changed(e), -ECHILD);
2448 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
2b0c9ef7 2449 assert_return(e->state == SD_EVENT_INITIAL, -EBUSY);
da7e457c 2450
6203e07a 2451 if (e->exit_requested)
c45a5a74 2452 goto pending;
fd38203a
LP
2453
2454 e->iteration++;
2455
0be6c2f6 2456 e->state = SD_EVENT_PREPARING;
fd38203a 2457 r = event_prepare(e);
0be6c2f6 2458 e->state = SD_EVENT_INITIAL;
fd38203a 2459 if (r < 0)
c45a5a74 2460 return r;
fd38203a 2461
6a0f1f6d
LP
2462 r = event_arm_timer(e, &e->realtime);
2463 if (r < 0)
c45a5a74 2464 return r;
6a0f1f6d 2465
a8548816
TG
2466 r = event_arm_timer(e, &e->boottime);
2467 if (r < 0)
c45a5a74 2468 return r;
a8548816 2469
6a0f1f6d
LP
2470 r = event_arm_timer(e, &e->monotonic);
2471 if (r < 0)
c45a5a74 2472 return r;
6a0f1f6d
LP
2473
2474 r = event_arm_timer(e, &e->realtime_alarm);
1b5995b0 2475 if (r < 0)
c45a5a74 2476 return r;
fd38203a 2477
6a0f1f6d 2478 r = event_arm_timer(e, &e->boottime_alarm);
1b5995b0 2479 if (r < 0)
c45a5a74 2480 return r;
fd38203a 2481
1b5995b0 2482 if (event_next_pending(e) || e->need_process_child)
c45a5a74
TG
2483 goto pending;
2484
2b0c9ef7 2485 e->state = SD_EVENT_ARMED;
c45a5a74
TG
2486
2487 return 0;
2488
2489pending:
2b0c9ef7 2490 e->state = SD_EVENT_ARMED;
6d148a84
TG
2491 r = sd_event_wait(e, 0);
2492 if (r == 0)
2b0c9ef7 2493 e->state = SD_EVENT_ARMED;
6d148a84
TG
2494
2495 return r;
c45a5a74
TG
2496}
2497
2498_public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
2499 struct epoll_event *ev_queue;
2500 unsigned ev_queue_max;
2501 int r, m, i;
2502
2503 assert_return(e, -EINVAL);
2504 assert_return(!event_pid_changed(e), -ECHILD);
2505 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
2b0c9ef7 2506 assert_return(e->state == SD_EVENT_ARMED, -EBUSY);
c45a5a74
TG
2507
2508 if (e->exit_requested) {
2509 e->state = SD_EVENT_PENDING;
2510 return 1;
2511 }
6a0f1f6d 2512
1c724e9e 2513 ev_queue_max = MAX(e->n_sources, 1u);
15b38f93 2514 ev_queue = newa(struct epoll_event, ev_queue_max);
fd38203a 2515
15b38f93 2516 m = epoll_wait(e->epoll_fd, ev_queue, ev_queue_max,
c2ba3ad6 2517 timeout == (uint64_t) -1 ? -1 : (int) ((timeout + USEC_PER_MSEC - 1) / USEC_PER_MSEC));
da7e457c 2518 if (m < 0) {
c45a5a74
TG
2519 if (errno == EINTR) {
2520 e->state = SD_EVENT_PENDING;
2521 return 1;
2522 }
2523
2524 r = -errno;
da7e457c
LP
2525 goto finish;
2526 }
fd38203a 2527
46e8c825 2528 dual_timestamp_get(&e->timestamp);
6a0f1f6d 2529 e->timestamp_boottime = now(CLOCK_BOOTTIME);
fd38203a
LP
2530
2531 for (i = 0; i < m; i++) {
2532
9da4cb2b 2533 if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_WATCHDOG))
cde93897 2534 r = flush_timer(e, e->watchdog_fd, ev_queue[i].events, NULL);
9da4cb2b
LP
2535 else {
2536 WakeupType *t = ev_queue[i].data.ptr;
2537
2538 switch (*t) {
2539
2540 case WAKEUP_EVENT_SOURCE:
2541 r = process_io(e, ev_queue[i].data.ptr, ev_queue[i].events);
2542 break;
fd38203a 2543
9da4cb2b
LP
2544 case WAKEUP_CLOCK_DATA: {
2545 struct clock_data *d = ev_queue[i].data.ptr;
2546 r = flush_timer(e, d->fd, ev_queue[i].events, &d->next);
2547 break;
2548 }
2549
2550 case WAKEUP_SIGNAL_DATA:
2551 r = process_signal(e, ev_queue[i].data.ptr, ev_queue[i].events);
2552 break;
2553
2554 default:
2555 assert_not_reached("Invalid wake-up pointer");
2556 }
2557 }
fd38203a 2558 if (r < 0)
da7e457c 2559 goto finish;
fd38203a
LP
2560 }
2561
cde93897
LP
2562 r = process_watchdog(e);
2563 if (r < 0)
2564 goto finish;
2565
6a0f1f6d
LP
2566 r = process_timer(e, e->timestamp.realtime, &e->realtime);
2567 if (r < 0)
2568 goto finish;
2569
a8548816
TG
2570 r = process_timer(e, e->timestamp_boottime, &e->boottime);
2571 if (r < 0)
2572 goto finish;
2573
6a0f1f6d
LP
2574 r = process_timer(e, e->timestamp.monotonic, &e->monotonic);
2575 if (r < 0)
2576 goto finish;
2577
2578 r = process_timer(e, e->timestamp.realtime, &e->realtime_alarm);
fd38203a 2579 if (r < 0)
da7e457c 2580 goto finish;
fd38203a 2581
6a0f1f6d 2582 r = process_timer(e, e->timestamp_boottime, &e->boottime_alarm);
fd38203a 2583 if (r < 0)
da7e457c 2584 goto finish;
fd38203a 2585
c2ba3ad6 2586 if (e->need_process_child) {
fd38203a
LP
2587 r = process_child(e);
2588 if (r < 0)
da7e457c 2589 goto finish;
fd38203a
LP
2590 }
2591
c45a5a74
TG
2592 if (event_next_pending(e)) {
2593 e->state = SD_EVENT_PENDING;
2594
2595 return 1;
da7e457c
LP
2596 }
2597
c45a5a74 2598 r = 0;
fd38203a 2599
da7e457c 2600finish:
2b0c9ef7 2601 e->state = SD_EVENT_INITIAL;
da7e457c
LP
2602
2603 return r;
fd38203a
LP
2604}
2605
c45a5a74
TG
2606_public_ int sd_event_dispatch(sd_event *e) {
2607 sd_event_source *p;
2608 int r;
2609
2610 assert_return(e, -EINVAL);
2611 assert_return(!event_pid_changed(e), -ECHILD);
2612 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
2613 assert_return(e->state == SD_EVENT_PENDING, -EBUSY);
2614
2615 if (e->exit_requested)
2616 return dispatch_exit(e);
2617
2618 p = event_next_pending(e);
2619 if (p) {
2620 sd_event_ref(e);
2621
2622 e->state = SD_EVENT_RUNNING;
2623 r = source_dispatch(p);
2b0c9ef7 2624 e->state = SD_EVENT_INITIAL;
c45a5a74
TG
2625
2626 sd_event_unref(e);
2627
2628 return r;
2629 }
2630
2b0c9ef7 2631 e->state = SD_EVENT_INITIAL;
c45a5a74
TG
2632
2633 return 1;
2634}
2635
34b87517
VC
2636static void event_log_delays(sd_event *e) {
2637 char b[ELEMENTSOF(e->delays) * DECIMAL_STR_MAX(unsigned) + 1];
34a6843d
VC
2638 unsigned i;
2639 int o;
34b87517
VC
2640
2641 for (i = o = 0; i < ELEMENTSOF(e->delays); i++) {
2642 o += snprintf(&b[o], sizeof(b) - o, "%u ", e->delays[i]);
2643 e->delays[i] = 0;
2644 }
34a6843d 2645 log_debug("Event loop iterations: %.*s", o, b);
34b87517
VC
2646}
2647
c45a5a74
TG
2648_public_ int sd_event_run(sd_event *e, uint64_t timeout) {
2649 int r;
2650
2651 assert_return(e, -EINVAL);
2652 assert_return(!event_pid_changed(e), -ECHILD);
2653 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
2b0c9ef7 2654 assert_return(e->state == SD_EVENT_INITIAL, -EBUSY);
c45a5a74 2655
34b87517
VC
2656 if (e->profile_delays && e->last_run) {
2657 usec_t this_run;
2658 unsigned l;
2659
2660 this_run = now(CLOCK_MONOTONIC);
2661
2662 l = u64log2(this_run - e->last_run);
2663 assert(l < sizeof(e->delays));
2664 e->delays[l]++;
2665
2666 if (this_run - e->last_log >= 5*USEC_PER_SEC) {
2667 event_log_delays(e);
2668 e->last_log = this_run;
2669 }
2670 }
2671
c45a5a74 2672 r = sd_event_prepare(e);
53bac4e0
LP
2673 if (r == 0)
2674 /* There was nothing? Then wait... */
2675 r = sd_event_wait(e, timeout);
c45a5a74 2676
34b87517
VC
2677 if (e->profile_delays)
2678 e->last_run = now(CLOCK_MONOTONIC);
2679
02d30981 2680 if (r > 0) {
53bac4e0 2681 /* There's something now, then let's dispatch it */
02d30981
TG
2682 r = sd_event_dispatch(e);
2683 if (r < 0)
2684 return r;
53bac4e0
LP
2685
2686 return 1;
2687 }
2688
2689 return r;
c45a5a74
TG
2690}
2691
f7262a9f 2692_public_ int sd_event_loop(sd_event *e) {
fd38203a
LP
2693 int r;
2694
da7e457c
LP
2695 assert_return(e, -EINVAL);
2696 assert_return(!event_pid_changed(e), -ECHILD);
2b0c9ef7 2697 assert_return(e->state == SD_EVENT_INITIAL, -EBUSY);
da7e457c
LP
2698
2699 sd_event_ref(e);
fd38203a 2700
da7e457c 2701 while (e->state != SD_EVENT_FINISHED) {
fd38203a
LP
2702 r = sd_event_run(e, (uint64_t) -1);
2703 if (r < 0)
da7e457c 2704 goto finish;
fd38203a
LP
2705 }
2706
6203e07a 2707 r = e->exit_code;
da7e457c
LP
2708
2709finish:
2710 sd_event_unref(e);
2711 return r;
fd38203a
LP
2712}
2713
9b364545
TG
2714_public_ int sd_event_get_fd(sd_event *e) {
2715
2716 assert_return(e, -EINVAL);
2717 assert_return(!event_pid_changed(e), -ECHILD);
2718
2719 return e->epoll_fd;
2720}
2721
f7262a9f 2722_public_ int sd_event_get_state(sd_event *e) {
da7e457c
LP
2723 assert_return(e, -EINVAL);
2724 assert_return(!event_pid_changed(e), -ECHILD);
2725
2726 return e->state;
2727}
2728
6203e07a 2729_public_ int sd_event_get_exit_code(sd_event *e, int *code) {
da7e457c 2730 assert_return(e, -EINVAL);
6203e07a 2731 assert_return(code, -EINVAL);
da7e457c 2732 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 2733
6203e07a
LP
2734 if (!e->exit_requested)
2735 return -ENODATA;
2736
2737 *code = e->exit_code;
2738 return 0;
fd38203a
LP
2739}
2740
6203e07a 2741_public_ int sd_event_exit(sd_event *e, int code) {
da7e457c
LP
2742 assert_return(e, -EINVAL);
2743 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
2744 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 2745
6203e07a
LP
2746 e->exit_requested = true;
2747 e->exit_code = code;
2748
fd38203a
LP
2749 return 0;
2750}
46e8c825 2751
6a0f1f6d 2752_public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) {
46e8c825
LP
2753 assert_return(e, -EINVAL);
2754 assert_return(usec, -EINVAL);
46e8c825 2755 assert_return(!event_pid_changed(e), -ECHILD);
2c86ba5a
ZJS
2756 assert_return(IN_SET(clock,
2757 CLOCK_REALTIME,
2758 CLOCK_REALTIME_ALARM,
2759 CLOCK_MONOTONIC,
2760 CLOCK_BOOTTIME,
2761 CLOCK_BOOTTIME_ALARM), -EOPNOTSUPP);
46e8c825 2762
38a03f06
LP
2763 if (!dual_timestamp_is_set(&e->timestamp)) {
2764 /* Implicitly fall back to now() if we never ran
2765 * before and thus have no cached time. */
2766 *usec = now(clock);
2767 return 1;
2768 }
46e8c825 2769
6a0f1f6d
LP
2770 switch (clock) {
2771
2772 case CLOCK_REALTIME:
2773 case CLOCK_REALTIME_ALARM:
2774 *usec = e->timestamp.realtime;
2775 break;
2776
2777 case CLOCK_MONOTONIC:
2778 *usec = e->timestamp.monotonic;
2779 break;
2780
2c86ba5a 2781 default:
6a0f1f6d
LP
2782 *usec = e->timestamp_boottime;
2783 break;
2784 }
46e8c825 2785
46e8c825
LP
2786 return 0;
2787}
afc6adb5
LP
2788
2789_public_ int sd_event_default(sd_event **ret) {
2790
ec202eae 2791 static thread_local sd_event *default_event = NULL;
39883f62 2792 sd_event *e = NULL;
afc6adb5
LP
2793 int r;
2794
2795 if (!ret)
2796 return !!default_event;
2797
2798 if (default_event) {
2799 *ret = sd_event_ref(default_event);
2800 return 0;
2801 }
2802
2803 r = sd_event_new(&e);
2804 if (r < 0)
2805 return r;
2806
2807 e->default_event_ptr = &default_event;
2808 e->tid = gettid();
2809 default_event = e;
2810
2811 *ret = e;
2812 return 1;
2813}
2814
2815_public_ int sd_event_get_tid(sd_event *e, pid_t *tid) {
2816 assert_return(e, -EINVAL);
2817 assert_return(tid, -EINVAL);
76b54375 2818 assert_return(!event_pid_changed(e), -ECHILD);
afc6adb5 2819
76b54375
LP
2820 if (e->tid != 0) {
2821 *tid = e->tid;
2822 return 0;
2823 }
2824
2825 return -ENXIO;
afc6adb5 2826}
cde93897
LP
2827
2828_public_ int sd_event_set_watchdog(sd_event *e, int b) {
2829 int r;
2830
2831 assert_return(e, -EINVAL);
8f726607 2832 assert_return(!event_pid_changed(e), -ECHILD);
cde93897
LP
2833
2834 if (e->watchdog == !!b)
2835 return e->watchdog;
2836
2837 if (b) {
2838 struct epoll_event ev = {};
cde93897 2839
09812eb7
LP
2840 r = sd_watchdog_enabled(false, &e->watchdog_period);
2841 if (r <= 0)
cde93897 2842 return r;
cde93897
LP
2843
2844 /* Issue first ping immediately */
2845 sd_notify(false, "WATCHDOG=1");
2846 e->watchdog_last = now(CLOCK_MONOTONIC);
2847
2848 e->watchdog_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
2849 if (e->watchdog_fd < 0)
2850 return -errno;
2851
2852 r = arm_watchdog(e);
2853 if (r < 0)
2854 goto fail;
2855
2856 ev.events = EPOLLIN;
2857 ev.data.ptr = INT_TO_PTR(SOURCE_WATCHDOG);
2858
2859 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, e->watchdog_fd, &ev);
2860 if (r < 0) {
2861 r = -errno;
2862 goto fail;
2863 }
2864
2865 } else {
2866 if (e->watchdog_fd >= 0) {
2867 epoll_ctl(e->epoll_fd, EPOLL_CTL_DEL, e->watchdog_fd, NULL);
03e334a1 2868 e->watchdog_fd = safe_close(e->watchdog_fd);
cde93897
LP
2869 }
2870 }
2871
2872 e->watchdog = !!b;
2873 return e->watchdog;
2874
2875fail:
03e334a1 2876 e->watchdog_fd = safe_close(e->watchdog_fd);
cde93897
LP
2877 return r;
2878}
8f726607
LP
2879
2880_public_ int sd_event_get_watchdog(sd_event *e) {
2881 assert_return(e, -EINVAL);
2882 assert_return(!event_pid_changed(e), -ECHILD);
2883
2884 return e->watchdog;
2885}