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