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