]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-event/sd-event.c
gitignore: ignore .swp files
[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
ZJS
1922 assert(e->signal_sources);
1923
305f78bf 1924 assert_return(events == EPOLLIN, -EIO);
fd38203a
LP
1925
1926 for (;;) {
0eb2e0e3
ZJS
1927 struct signalfd_siginfo si;
1928 ssize_t ss;
fd38203a
LP
1929 sd_event_source *s;
1930
1931 ss = read(e->signal_fd, &si, sizeof(si));
1932 if (ss < 0) {
1933 if (errno == EAGAIN || errno == EINTR)
1934 return read_one;
1935
1936 return -errno;
1937 }
1938
8d35dae7 1939 if (_unlikely_(ss != sizeof(si)))
fd38203a
LP
1940 return -EIO;
1941
1942 read_one = true;
1943
0eb2e0e3 1944 s = e->signal_sources[si.ssi_signo];
fd38203a
LP
1945 if (si.ssi_signo == SIGCHLD) {
1946 r = process_child(e);
1947 if (r < 0)
1948 return r;
0eb2e0e3 1949 if (r > 0 || !s)
fd38203a 1950 continue;
0eb2e0e3 1951 } else
fd38203a
LP
1952 if (!s)
1953 return -EIO;
fd38203a
LP
1954
1955 s->signal.siginfo = si;
1956 r = source_set_pending(s, true);
1957 if (r < 0)
1958 return r;
1959 }
fd38203a
LP
1960}
1961
1962static int source_dispatch(sd_event_source *s) {
fe8245eb 1963 int r = 0;
fd38203a
LP
1964
1965 assert(s);
6203e07a 1966 assert(s->pending || s->type == SOURCE_EXIT);
fd38203a 1967
6203e07a 1968 if (s->type != SOURCE_DEFER && s->type != SOURCE_EXIT) {
da7e457c
LP
1969 r = source_set_pending(s, false);
1970 if (r < 0)
1971 return r;
1972 }
fd38203a 1973
6e9feda3
LP
1974 if (s->type != SOURCE_POST) {
1975 sd_event_source *z;
1976 Iterator i;
1977
1978 /* If we execute a non-post source, let's mark all
1979 * post sources as pending */
1980
1981 SET_FOREACH(z, s->event->post_sources, i) {
1982 if (z->enabled == SD_EVENT_OFF)
1983 continue;
1984
1985 r = source_set_pending(z, true);
1986 if (r < 0)
1987 return r;
1988 }
1989 }
1990
baf76283
LP
1991 if (s->enabled == SD_EVENT_ONESHOT) {
1992 r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
fd38203a
LP
1993 if (r < 0)
1994 return r;
1995 }
1996
12179984 1997 s->dispatching = true;
b7484e2a 1998
fd38203a
LP
1999 switch (s->type) {
2000
2001 case SOURCE_IO:
2002 r = s->io.callback(s, s->io.fd, s->io.revents, s->userdata);
2003 break;
2004
6a0f1f6d
LP
2005 case SOURCE_TIME_REALTIME:
2006 case SOURCE_TIME_MONOTONIC:
2007 case SOURCE_TIME_REALTIME_ALARM:
2008 case SOURCE_TIME_BOOTTIME_ALARM:
fd38203a
LP
2009 r = s->time.callback(s, s->time.next, s->userdata);
2010 break;
2011
2012 case SOURCE_SIGNAL:
2013 r = s->signal.callback(s, &s->signal.siginfo, s->userdata);
2014 break;
2015
08cd1552
LP
2016 case SOURCE_CHILD: {
2017 bool zombie;
2018
2019 zombie = s->child.siginfo.si_code == CLD_EXITED ||
2020 s->child.siginfo.si_code == CLD_KILLED ||
2021 s->child.siginfo.si_code == CLD_DUMPED;
2022
fd38203a 2023 r = s->child.callback(s, &s->child.siginfo, s->userdata);
08cd1552
LP
2024
2025 /* Now, reap the PID for good. */
2026 if (zombie)
2027 waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|WEXITED);
2028
fd38203a 2029 break;
08cd1552 2030 }
fd38203a
LP
2031
2032 case SOURCE_DEFER:
2033 r = s->defer.callback(s, s->userdata);
2034 break;
da7e457c 2035
6e9feda3
LP
2036 case SOURCE_POST:
2037 r = s->post.callback(s, s->userdata);
2038 break;
2039
6203e07a
LP
2040 case SOURCE_EXIT:
2041 r = s->exit.callback(s, s->userdata);
da7e457c 2042 break;
9d3e3aa5
LP
2043
2044 case SOURCE_WATCHDOG:
a71fe8b8 2045 case _SOURCE_EVENT_SOURCE_TYPE_MAX:
9f2a50a3 2046 case _SOURCE_EVENT_SOURCE_TYPE_INVALID:
9d3e3aa5 2047 assert_not_reached("Wut? I shouldn't exist.");
fd38203a
LP
2048 }
2049
12179984
LP
2050 s->dispatching = false;
2051
2052 if (r < 0)
6203e07a 2053 log_debug("Event source %p returned error, disabling: %s", s, strerror(-r));
12179984
LP
2054
2055 if (s->n_ref == 0)
2056 source_free(s);
2057 else if (r < 0)
6203e07a 2058 sd_event_source_set_enabled(s, SD_EVENT_OFF);
b7484e2a 2059
6203e07a 2060 return 1;
fd38203a
LP
2061}
2062
2063static int event_prepare(sd_event *e) {
2064 int r;
2065
2066 assert(e);
2067
2068 for (;;) {
2069 sd_event_source *s;
2070
2071 s = prioq_peek(e->prepare);
baf76283 2072 if (!s || s->prepare_iteration == e->iteration || s->enabled == SD_EVENT_OFF)
fd38203a
LP
2073 break;
2074
2075 s->prepare_iteration = e->iteration;
2076 r = prioq_reshuffle(e->prepare, s, &s->prepare_index);
2077 if (r < 0)
2078 return r;
2079
2080 assert(s->prepare);
12179984
LP
2081
2082 s->dispatching = true;
fd38203a 2083 r = s->prepare(s, s->userdata);
12179984
LP
2084 s->dispatching = false;
2085
fd38203a 2086 if (r < 0)
12179984 2087 log_debug("Prepare callback of event source %p returned error, disabling: %s", s, strerror(-r));
fd38203a 2088
12179984
LP
2089 if (s->n_ref == 0)
2090 source_free(s);
2091 else if (r < 0)
2092 sd_event_source_set_enabled(s, SD_EVENT_OFF);
fd38203a
LP
2093 }
2094
2095 return 0;
2096}
2097
6203e07a 2098static int dispatch_exit(sd_event *e) {
da7e457c
LP
2099 sd_event_source *p;
2100 int r;
2101
2102 assert(e);
2103
6203e07a 2104 p = prioq_peek(e->exit);
baf76283 2105 if (!p || p->enabled == SD_EVENT_OFF) {
da7e457c
LP
2106 e->state = SD_EVENT_FINISHED;
2107 return 0;
2108 }
2109
2110 sd_event_ref(e);
2111 e->iteration++;
6203e07a 2112 e->state = SD_EVENT_EXITING;
da7e457c
LP
2113
2114 r = source_dispatch(p);
2115
2116 e->state = SD_EVENT_PASSIVE;
2117 sd_event_unref(e);
2118
2119 return r;
2120}
2121
c2ba3ad6
LP
2122static sd_event_source* event_next_pending(sd_event *e) {
2123 sd_event_source *p;
2124
da7e457c
LP
2125 assert(e);
2126
c2ba3ad6
LP
2127 p = prioq_peek(e->pending);
2128 if (!p)
2129 return NULL;
2130
baf76283 2131 if (p->enabled == SD_EVENT_OFF)
c2ba3ad6
LP
2132 return NULL;
2133
2134 return p;
2135}
2136
cde93897
LP
2137static int arm_watchdog(sd_event *e) {
2138 struct itimerspec its = {};
2139 usec_t t;
2140 int r;
2141
2142 assert(e);
2143 assert(e->watchdog_fd >= 0);
2144
2145 t = sleep_between(e,
2146 e->watchdog_last + (e->watchdog_period / 2),
2147 e->watchdog_last + (e->watchdog_period * 3 / 4));
2148
2149 timespec_store(&its.it_value, t);
2150
75145780
LP
2151 /* Make sure we never set the watchdog to 0, which tells the
2152 * kernel to disable it. */
2153 if (its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0)
2154 its.it_value.tv_nsec = 1;
2155
cde93897
LP
2156 r = timerfd_settime(e->watchdog_fd, TFD_TIMER_ABSTIME, &its, NULL);
2157 if (r < 0)
2158 return -errno;
2159
2160 return 0;
2161}
2162
2163static int process_watchdog(sd_event *e) {
2164 assert(e);
2165
2166 if (!e->watchdog)
2167 return 0;
2168
2169 /* Don't notify watchdog too often */
2170 if (e->watchdog_last + e->watchdog_period / 4 > e->timestamp.monotonic)
2171 return 0;
2172
2173 sd_notify(false, "WATCHDOG=1");
2174 e->watchdog_last = e->timestamp.monotonic;
2175
2176 return arm_watchdog(e);
2177}
2178
f7262a9f 2179_public_ int sd_event_run(sd_event *e, uint64_t timeout) {
15b38f93
LP
2180 struct epoll_event *ev_queue;
2181 unsigned ev_queue_max;
fd38203a 2182 sd_event_source *p;
305f78bf 2183 int r, i, m;
eec6022c 2184 bool timedout;
fd38203a 2185
da7e457c
LP
2186 assert_return(e, -EINVAL);
2187 assert_return(!event_pid_changed(e), -ECHILD);
2188 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
2189 assert_return(e->state == SD_EVENT_PASSIVE, -EBUSY);
2190
6203e07a
LP
2191 if (e->exit_requested)
2192 return dispatch_exit(e);
fd38203a 2193
da7e457c 2194 sd_event_ref(e);
fd38203a 2195 e->iteration++;
da7e457c 2196 e->state = SD_EVENT_RUNNING;
fd38203a
LP
2197
2198 r = event_prepare(e);
2199 if (r < 0)
da7e457c 2200 goto finish;
fd38203a 2201
6a0f1f6d
LP
2202 r = event_arm_timer(e, &e->realtime);
2203 if (r < 0)
2204 goto finish;
2205
2206 r = event_arm_timer(e, &e->monotonic);
2207 if (r < 0)
2208 goto finish;
2209
2210 r = event_arm_timer(e, &e->realtime_alarm);
1b5995b0
LP
2211 if (r < 0)
2212 goto finish;
fd38203a 2213
6a0f1f6d 2214 r = event_arm_timer(e, &e->boottime_alarm);
1b5995b0
LP
2215 if (r < 0)
2216 goto finish;
fd38203a 2217
1b5995b0
LP
2218 if (event_next_pending(e) || e->need_process_child)
2219 timeout = 0;
6a0f1f6d 2220
15b38f93
LP
2221 ev_queue_max = CLAMP(e->n_sources, 1U, EPOLL_QUEUE_MAX);
2222 ev_queue = newa(struct epoll_event, ev_queue_max);
fd38203a 2223
15b38f93 2224 m = epoll_wait(e->epoll_fd, ev_queue, ev_queue_max,
c2ba3ad6 2225 timeout == (uint64_t) -1 ? -1 : (int) ((timeout + USEC_PER_MSEC - 1) / USEC_PER_MSEC));
da7e457c 2226 if (m < 0) {
ff003106 2227 r = errno == EAGAIN || errno == EINTR ? 1 : -errno;
da7e457c
LP
2228 goto finish;
2229 }
fd38203a 2230
eec6022c
LP
2231 timedout = m == 0;
2232
46e8c825 2233 dual_timestamp_get(&e->timestamp);
6a0f1f6d 2234 e->timestamp_boottime = now(CLOCK_BOOTTIME);
fd38203a
LP
2235
2236 for (i = 0; i < m; i++) {
2237
6a0f1f6d
LP
2238 if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_REALTIME))
2239 r = flush_timer(e, e->realtime.fd, ev_queue[i].events, &e->realtime.next);
2240 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_MONOTONIC))
2241 r = flush_timer(e, e->monotonic.fd, ev_queue[i].events, &e->monotonic.next);
2242 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_REALTIME_ALARM))
2243 r = flush_timer(e, e->realtime_alarm.fd, ev_queue[i].events, &e->realtime_alarm.next);
2244 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_BOOTTIME_ALARM))
2245 r = flush_timer(e, e->boottime_alarm.fd, ev_queue[i].events, &e->boottime_alarm.next);
fd38203a
LP
2246 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_SIGNAL))
2247 r = process_signal(e, ev_queue[i].events);
79e16ce3 2248 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_WATCHDOG))
cde93897 2249 r = flush_timer(e, e->watchdog_fd, ev_queue[i].events, NULL);
fd38203a
LP
2250 else
2251 r = process_io(e, ev_queue[i].data.ptr, ev_queue[i].events);
2252
2253 if (r < 0)
da7e457c 2254 goto finish;
fd38203a
LP
2255 }
2256
cde93897
LP
2257 r = process_watchdog(e);
2258 if (r < 0)
2259 goto finish;
2260
6a0f1f6d
LP
2261 r = process_timer(e, e->timestamp.realtime, &e->realtime);
2262 if (r < 0)
2263 goto finish;
2264
2265 r = process_timer(e, e->timestamp.monotonic, &e->monotonic);
2266 if (r < 0)
2267 goto finish;
2268
2269 r = process_timer(e, e->timestamp.realtime, &e->realtime_alarm);
fd38203a 2270 if (r < 0)
da7e457c 2271 goto finish;
fd38203a 2272
6a0f1f6d 2273 r = process_timer(e, e->timestamp_boottime, &e->boottime_alarm);
fd38203a 2274 if (r < 0)
da7e457c 2275 goto finish;
fd38203a 2276
c2ba3ad6 2277 if (e->need_process_child) {
fd38203a
LP
2278 r = process_child(e);
2279 if (r < 0)
da7e457c 2280 goto finish;
fd38203a
LP
2281 }
2282
c2ba3ad6 2283 p = event_next_pending(e);
da7e457c 2284 if (!p) {
eec6022c 2285 r = !timedout;
da7e457c
LP
2286 goto finish;
2287 }
2288
2289 r = source_dispatch(p);
fd38203a 2290
da7e457c
LP
2291finish:
2292 e->state = SD_EVENT_PASSIVE;
2293 sd_event_unref(e);
2294
2295 return r;
fd38203a
LP
2296}
2297
f7262a9f 2298_public_ int sd_event_loop(sd_event *e) {
fd38203a
LP
2299 int r;
2300
da7e457c
LP
2301 assert_return(e, -EINVAL);
2302 assert_return(!event_pid_changed(e), -ECHILD);
2303 assert_return(e->state == SD_EVENT_PASSIVE, -EBUSY);
2304
2305 sd_event_ref(e);
fd38203a 2306
da7e457c 2307 while (e->state != SD_EVENT_FINISHED) {
fd38203a
LP
2308 r = sd_event_run(e, (uint64_t) -1);
2309 if (r < 0)
da7e457c 2310 goto finish;
fd38203a
LP
2311 }
2312
6203e07a 2313 r = e->exit_code;
da7e457c
LP
2314
2315finish:
2316 sd_event_unref(e);
2317 return r;
fd38203a
LP
2318}
2319
f7262a9f 2320_public_ int sd_event_get_state(sd_event *e) {
da7e457c
LP
2321 assert_return(e, -EINVAL);
2322 assert_return(!event_pid_changed(e), -ECHILD);
2323
2324 return e->state;
2325}
2326
6203e07a 2327_public_ int sd_event_get_exit_code(sd_event *e, int *code) {
da7e457c 2328 assert_return(e, -EINVAL);
6203e07a 2329 assert_return(code, -EINVAL);
da7e457c 2330 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 2331
6203e07a
LP
2332 if (!e->exit_requested)
2333 return -ENODATA;
2334
2335 *code = e->exit_code;
2336 return 0;
fd38203a
LP
2337}
2338
6203e07a 2339_public_ int sd_event_exit(sd_event *e, int code) {
da7e457c
LP
2340 assert_return(e, -EINVAL);
2341 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
2342 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 2343
6203e07a
LP
2344 e->exit_requested = true;
2345 e->exit_code = code;
2346
fd38203a
LP
2347 return 0;
2348}
46e8c825 2349
6a0f1f6d 2350_public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) {
46e8c825
LP
2351 assert_return(e, -EINVAL);
2352 assert_return(usec, -EINVAL);
46e8c825
LP
2353 assert_return(!event_pid_changed(e), -ECHILD);
2354
6a0f1f6d
LP
2355 /* If we haven't run yet, just get the actual time */
2356 if (!dual_timestamp_is_set(&e->timestamp))
2357 return -ENODATA;
46e8c825 2358
6a0f1f6d
LP
2359 switch (clock) {
2360
2361 case CLOCK_REALTIME:
2362 case CLOCK_REALTIME_ALARM:
2363 *usec = e->timestamp.realtime;
2364 break;
2365
2366 case CLOCK_MONOTONIC:
2367 *usec = e->timestamp.monotonic;
2368 break;
2369
2370 case CLOCK_BOOTTIME_ALARM:
2371 *usec = e->timestamp_boottime;
2372 break;
2373 }
46e8c825 2374
46e8c825
LP
2375 return 0;
2376}
afc6adb5
LP
2377
2378_public_ int sd_event_default(sd_event **ret) {
2379
ec202eae 2380 static thread_local sd_event *default_event = NULL;
39883f62 2381 sd_event *e = NULL;
afc6adb5
LP
2382 int r;
2383
2384 if (!ret)
2385 return !!default_event;
2386
2387 if (default_event) {
2388 *ret = sd_event_ref(default_event);
2389 return 0;
2390 }
2391
2392 r = sd_event_new(&e);
2393 if (r < 0)
2394 return r;
2395
2396 e->default_event_ptr = &default_event;
2397 e->tid = gettid();
2398 default_event = e;
2399
2400 *ret = e;
2401 return 1;
2402}
2403
2404_public_ int sd_event_get_tid(sd_event *e, pid_t *tid) {
2405 assert_return(e, -EINVAL);
2406 assert_return(tid, -EINVAL);
76b54375 2407 assert_return(!event_pid_changed(e), -ECHILD);
afc6adb5 2408
76b54375
LP
2409 if (e->tid != 0) {
2410 *tid = e->tid;
2411 return 0;
2412 }
2413
2414 return -ENXIO;
afc6adb5 2415}
cde93897
LP
2416
2417_public_ int sd_event_set_watchdog(sd_event *e, int b) {
2418 int r;
2419
2420 assert_return(e, -EINVAL);
8f726607 2421 assert_return(!event_pid_changed(e), -ECHILD);
cde93897
LP
2422
2423 if (e->watchdog == !!b)
2424 return e->watchdog;
2425
2426 if (b) {
2427 struct epoll_event ev = {};
cde93897 2428
09812eb7
LP
2429 r = sd_watchdog_enabled(false, &e->watchdog_period);
2430 if (r <= 0)
cde93897 2431 return r;
cde93897
LP
2432
2433 /* Issue first ping immediately */
2434 sd_notify(false, "WATCHDOG=1");
2435 e->watchdog_last = now(CLOCK_MONOTONIC);
2436
2437 e->watchdog_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
2438 if (e->watchdog_fd < 0)
2439 return -errno;
2440
2441 r = arm_watchdog(e);
2442 if (r < 0)
2443 goto fail;
2444
2445 ev.events = EPOLLIN;
2446 ev.data.ptr = INT_TO_PTR(SOURCE_WATCHDOG);
2447
2448 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, e->watchdog_fd, &ev);
2449 if (r < 0) {
2450 r = -errno;
2451 goto fail;
2452 }
2453
2454 } else {
2455 if (e->watchdog_fd >= 0) {
2456 epoll_ctl(e->epoll_fd, EPOLL_CTL_DEL, e->watchdog_fd, NULL);
03e334a1 2457 e->watchdog_fd = safe_close(e->watchdog_fd);
cde93897
LP
2458 }
2459 }
2460
2461 e->watchdog = !!b;
2462 return e->watchdog;
2463
2464fail:
03e334a1 2465 e->watchdog_fd = safe_close(e->watchdog_fd);
cde93897
LP
2466 return r;
2467}
8f726607
LP
2468
2469_public_ int sd_event_get_watchdog(sd_event *e) {
2470 assert_return(e, -EINVAL);
2471 assert_return(!event_pid_changed(e), -ECHILD);
2472
2473 return e->watchdog;
2474}