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