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