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