1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
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.
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.
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/>.
22 #include <sys/epoll.h>
23 #include <sys/timerfd.h>
31 #include "time-util.h"
36 #define EPOLL_QUEUE_MAX 64
37 #define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC)
39 typedef enum EventSourceType {
48 struct sd_event_source {
53 sd_prepare_handler_t prepare;
55 EventSourceType type:4;
56 sd_event_mute_t mute:3;
60 unsigned pending_index;
61 unsigned prepare_index;
62 unsigned pending_iteration;
63 unsigned prepare_iteration;
67 sd_io_handler_t callback;
74 sd_time_handler_t callback;
75 usec_t next, accuracy;
76 unsigned earliest_index;
77 unsigned latest_index;
80 sd_signal_handler_t callback;
81 struct signalfd_siginfo siginfo;
85 sd_child_handler_t callback;
91 sd_defer_handler_t callback;
107 /* For both clocks we maintain two priority queues each, one
108 * ordered for the earliest times the events may be
109 * dispatched, and one ordered by the latest times they must
110 * have been dispatched. The range between the top entries in
111 * the two prioqs is the time window we can freely schedule
113 Prioq *monotonic_earliest;
114 Prioq *monotonic_latest;
115 Prioq *realtime_earliest;
116 Prioq *realtime_latest;
119 sd_event_source **signal_sources;
121 Hashmap *child_sources;
122 unsigned n_unmuted_child_sources;
126 usec_t realtime_next, monotonic_next;
131 bool need_process_child;
134 static int pending_prioq_compare(const void *a, const void *b) {
135 const sd_event_source *x = a, *y = b;
140 /* Unmuted ones first */
141 if (x->mute != SD_EVENT_MUTED && y->mute == SD_EVENT_MUTED)
143 if (x->mute == SD_EVENT_MUTED && y->mute != SD_EVENT_MUTED)
146 /* Lower priority values first */
147 if (x->priority < y->priority)
149 if (x->priority > y->priority)
152 /* Older entries first */
153 if (x->pending_iteration < y->pending_iteration)
155 if (x->pending_iteration > y->pending_iteration)
158 /* Stability for the rest */
167 static int prepare_prioq_compare(const void *a, const void *b) {
168 const sd_event_source *x = a, *y = b;
173 /* Move most recently prepared ones last, so that we can stop
174 * preparing as soon as we hit one that has already been
175 * prepared in the current iteration */
176 if (x->prepare_iteration < y->prepare_iteration)
178 if (x->prepare_iteration > y->prepare_iteration)
181 /* Unmuted ones first */
182 if (x->mute != SD_EVENT_MUTED && y->mute == SD_EVENT_MUTED)
184 if (x->mute == SD_EVENT_MUTED && y->mute != SD_EVENT_MUTED)
187 /* Lower priority values first */
188 if (x->priority < y->priority)
190 if (x->priority > y->priority)
193 /* Stability for the rest */
202 static int earliest_time_prioq_compare(const void *a, const void *b) {
203 const sd_event_source *x = a, *y = b;
205 assert(x->type == SOURCE_MONOTONIC || x->type == SOURCE_REALTIME);
206 assert(y->type == SOURCE_MONOTONIC || y->type == SOURCE_REALTIME);
208 /* Unmuted ones first */
209 if (x->mute != SD_EVENT_MUTED && y->mute == SD_EVENT_MUTED)
211 if (x->mute == SD_EVENT_MUTED && y->mute != SD_EVENT_MUTED)
214 /* Move the pending ones to the end */
215 if (!x->pending && y->pending)
217 if (x->pending && !y->pending)
221 if (x->time.next < y->time.next)
223 if (x->time.next > y->time.next)
226 /* Stability for the rest */
235 static int latest_time_prioq_compare(const void *a, const void *b) {
236 const sd_event_source *x = a, *y = b;
238 assert(x->type == SOURCE_MONOTONIC || x->type == SOURCE_REALTIME);
239 assert(y->type == SOURCE_MONOTONIC || y->type == SOURCE_REALTIME);
241 /* Unmuted ones first */
242 if (x->mute != SD_EVENT_MUTED && y->mute == SD_EVENT_MUTED)
244 if (x->mute == SD_EVENT_MUTED && y->mute != SD_EVENT_MUTED)
247 /* Move the pending ones to the end */
248 if (!x->pending && y->pending)
250 if (x->pending && !y->pending)
254 if (x->time.next + x->time.accuracy < y->time.next + y->time.accuracy)
256 if (x->time.next + x->time.accuracy > y->time.next + y->time.accuracy)
259 /* Stability for the rest */
268 static void event_free(sd_event *e) {
271 if (e->epoll_fd >= 0)
272 close_nointr_nofail(e->epoll_fd);
274 if (e->signal_fd >= 0)
275 close_nointr_nofail(e->signal_fd);
277 if (e->realtime_fd >= 0)
278 close_nointr_nofail(e->realtime_fd);
280 if (e->monotonic_fd >= 0)
281 close_nointr_nofail(e->monotonic_fd);
283 prioq_free(e->pending);
284 prioq_free(e->prepare);
285 prioq_free(e->monotonic_earliest);
286 prioq_free(e->monotonic_latest);
287 prioq_free(e->realtime_earliest);
288 prioq_free(e->realtime_latest);
290 free(e->signal_sources);
292 hashmap_free(e->child_sources);
296 int sd_event_new(sd_event** ret) {
303 e = new0(sd_event, 1);
307 e->n_ref = REFCNT_INIT;
308 e->signal_fd = e->realtime_fd = e->monotonic_fd = e->epoll_fd = -1;
309 e->realtime_next = e->monotonic_next = (usec_t) -1;
311 assert_se(sigemptyset(&e->sigset) == 0);
313 e->pending = prioq_new(pending_prioq_compare);
319 e->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
320 if (e->epoll_fd < 0) {
333 sd_event* sd_event_ref(sd_event *e) {
337 assert_se(REFCNT_INC(e->n_ref) >= 2);
342 sd_event* sd_event_unref(sd_event *e) {
346 if (REFCNT_DEC(e->n_ref) <= 0)
352 static int source_io_unregister(sd_event_source *s) {
356 assert(s->type == SOURCE_IO);
358 if (!s->io.registered)
361 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, s->io.fd, NULL);
365 s->io.registered = false;
369 static int source_io_register(sd_event_source *s, sd_event_mute_t m, uint32_t events) {
370 struct epoll_event ev = {};
374 assert(s->type == SOURCE_IO);
375 assert(m != SD_EVENT_MUTED);
380 if (m == SD_EVENT_ONESHOT)
381 ev.events |= EPOLLONESHOT;
383 if (s->io.registered)
384 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_MOD, s->io.fd, &ev);
386 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_ADD, s->io.fd, &ev);
391 s->io.registered = true;
396 static void source_free(sd_event_source *s) {
404 source_io_unregister(s);
408 case SOURCE_MONOTONIC:
409 prioq_remove(s->event->monotonic_earliest, s, &s->time.earliest_index);
410 prioq_remove(s->event->monotonic_latest, s, &s->time.latest_index);
413 case SOURCE_REALTIME:
414 prioq_remove(s->event->realtime_earliest, s, &s->time.earliest_index);
415 prioq_remove(s->event->realtime_latest, s, &s->time.latest_index);
419 if (s->signal.sig > 0) {
420 if (s->signal.sig != SIGCHLD || s->event->n_unmuted_child_sources == 0)
421 assert_se(sigdelset(&s->event->sigset, s->signal.sig) == 0);
423 if (s->event->signal_sources)
424 s->event->signal_sources[s->signal.sig] = NULL;
430 if (s->child.pid > 0) {
431 if (s->mute != SD_EVENT_MUTED) {
432 assert(s->event->n_unmuted_child_sources > 0);
433 s->event->n_unmuted_child_sources--;
436 if (!s->event->signal_sources || !s->event->signal_sources[SIGCHLD])
437 assert_se(sigdelset(&s->event->sigset, SIGCHLD) == 0);
439 hashmap_remove(s->event->child_sources, INT_TO_PTR(s->child.pid));
446 prioq_remove(s->event->pending, s, &s->pending_index);
449 prioq_remove(s->event->prepare, s, &s->prepare_index);
451 sd_event_unref(s->event);
457 static int source_set_pending(sd_event_source *s, bool b) {
468 s->pending_iteration = s->event->iteration;
470 r = prioq_put(s->event->pending, s, &s->pending_index);
476 assert_se(prioq_remove(s->event->pending, s, &s->pending_index));
481 static sd_event_source *source_new(sd_event *e, EventSourceType type) {
486 s = new0(sd_event_source, 1);
490 s->n_ref = REFCNT_INIT;
491 s->event = sd_event_ref(e);
493 s->mute = SD_EVENT_UNMUTED;
494 s->pending_index = s->prepare_index = PRIOQ_IDX_NULL;
503 sd_io_handler_t callback,
505 sd_event_source **ret) {
514 if (events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP))
521 s = source_new(e, SOURCE_IO);
526 s->io.events = events;
527 s->io.callback = callback;
528 s->userdata = userdata;
530 r = source_io_register(s, s->mute, events);
540 static int event_setup_timer_fd(
542 EventSourceType type,
546 struct epoll_event ev = {};
553 if (_likely_(*timer_fd >= 0))
556 fd = timerfd_create(id, TFD_NONBLOCK|TFD_CLOEXEC);
561 ev.data.ptr = INT_TO_PTR(type);
563 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, fd, &ev);
565 close_nointr_nofail(fd);
569 /* When we sleep for longer, we try to realign the wakeup to
570 the same time wihtin each second, so that events all across
571 the system can be coalesced into a single CPU
572 wakeup. However, let's take some system-specific randomness
573 for this value, so that in a network of systems with synced
574 clocks timer events are distributed a bit. Here, we
575 calculate a perturbation usec offset from the boot ID. */
577 if (sd_id128_get_boot(&bootid) >= 0)
578 e->perturb = (bootid.qwords[0] ^ bootid.qwords[1]) % USEC_PER_SEC;
584 static int event_add_time_internal(
586 EventSourceType type,
593 sd_time_handler_t callback,
595 sd_event_source **ret) {
606 if (usec == (uint64_t) -1)
608 if (accuracy == (uint64_t) -1)
616 *earliest = prioq_new(earliest_time_prioq_compare);
622 *latest = prioq_new(latest_time_prioq_compare);
628 r = event_setup_timer_fd(e, type, timer_fd, id);
633 s = source_new(e, type);
638 s->time.accuracy = accuracy == 0 ? DEFAULT_ACCURACY_USEC : accuracy;
639 s->time.callback = callback;
640 s->time.earliest_index = PRIOQ_IDX_NULL;
641 s->time.latest_index = PRIOQ_IDX_NULL;
642 s->userdata = userdata;
644 r = prioq_put(*earliest, s, &s->time.earliest_index);
648 r = prioq_put(*latest, s, &s->time.latest_index);
660 int sd_event_add_monotonic(sd_event *e, uint64_t usec, uint64_t accuracy, sd_time_handler_t callback, void *userdata, sd_event_source **ret) {
661 return event_add_time_internal(e, SOURCE_MONOTONIC, &e->monotonic_fd, CLOCK_MONOTONIC, &e->monotonic_earliest, &e->monotonic_latest, usec, accuracy, callback, userdata, ret);
664 int sd_event_add_realtime(sd_event *e, uint64_t usec, uint64_t accuracy, sd_time_handler_t callback, void *userdata, sd_event_source **ret) {
665 return event_add_time_internal(e, SOURCE_REALTIME, &e->realtime_fd, CLOCK_REALTIME, &e->realtime_earliest, &e->monotonic_latest, usec, accuracy, callback, userdata, ret);
668 static int event_update_signal_fd(sd_event *e) {
669 struct epoll_event ev = {};
675 add_to_epoll = e->signal_fd < 0;
677 r = signalfd(e->signal_fd, &e->sigset, SFD_NONBLOCK|SFD_CLOEXEC);
687 ev.data.ptr = INT_TO_PTR(SOURCE_SIGNAL);
689 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, e->signal_fd, &ev);
691 close_nointr_nofail(e->signal_fd);
700 int sd_event_add_signal(sd_event *e, int sig, sd_signal_handler_t callback, void *userdata, sd_event_source **ret) {
715 if (!e->signal_sources) {
716 e->signal_sources = new0(sd_event_source*, _NSIG);
717 if (!e->signal_sources)
719 } else if (e->signal_sources[sig])
722 s = source_new(e, SOURCE_SIGNAL);
727 s->signal.callback = callback;
728 s->userdata = userdata;
730 e->signal_sources[sig] = s;
731 assert_se(sigaddset(&e->sigset, sig) == 0);
733 if (sig != SIGCHLD || e->n_unmuted_child_sources == 0) {
734 r = event_update_signal_fd(e);
745 int sd_event_add_child(sd_event *e, pid_t pid, int options, sd_child_handler_t callback, void *userdata, sd_event_source **ret) {
753 if (options & ~(WEXITED|WSTOPPED|WCONTINUED))
760 r = hashmap_ensure_allocated(&e->child_sources, trivial_hash_func, trivial_compare_func);
764 if (hashmap_contains(e->child_sources, INT_TO_PTR(pid)))
767 s = source_new(e, SOURCE_CHILD);
772 s->child.options = options;
773 s->child.callback = callback;
774 s->userdata = userdata;
776 r = hashmap_put(e->child_sources, INT_TO_PTR(pid), s);
782 e->n_unmuted_child_sources ++;
784 assert_se(sigaddset(&e->sigset, SIGCHLD) == 0);
786 if (!e->signal_sources || !e->signal_sources[SIGCHLD]) {
787 r = event_update_signal_fd(e);
794 e->need_process_child = true;
800 int sd_event_add_defer(sd_event *e, sd_defer_handler_t callback, void *userdata, sd_event_source **ret) {
809 s = source_new(e, SOURCE_DEFER);
813 s->defer.callback = callback;
814 s->userdata = userdata;
816 r = source_set_pending(s, true);
826 sd_event_source* sd_event_source_ref(sd_event_source *s) {
830 assert_se(REFCNT_INC(s->n_ref) >= 2);
835 sd_event_source* sd_event_source_unref(sd_event_source *s) {
839 if (REFCNT_DEC(s->n_ref) <= 0)
845 int sd_event_source_get_pending(sd_event_source *s) {
852 int sd_event_source_get_io_fd(sd_event_source *s) {
855 if (s->type != SOURCE_IO)
861 int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) {
864 if (s->type != SOURCE_IO)
869 *events = s->io.events;
873 int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) {
878 if (!s->type != SOURCE_IO)
880 if (events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP))
883 if (s->io.events == events)
886 if (s->mute != SD_EVENT_MUTED) {
887 r = source_io_register(s, s->io.events, events);
892 s->io.events = events;
897 int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents) {
900 if (s->type != SOURCE_IO)
907 *revents = s->io.revents;
911 int sd_event_source_get_signal(sd_event_source *s) {
914 if (s->type != SOURCE_SIGNAL)
917 return s->signal.sig;
920 int sd_event_source_get_priority(sd_event_source *s, int *priority) {
927 int sd_event_source_set_priority(sd_event_source *s, int priority) {
931 if (s->priority == priority)
934 s->priority = priority;
937 prioq_reshuffle(s->event->pending, s, &s->pending_index);
940 prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
945 int sd_event_source_get_mute(sd_event_source *s, sd_event_mute_t *m) {
955 int sd_event_source_set_mute(sd_event_source *s, sd_event_mute_t m) {
960 if (m != SD_EVENT_MUTED && m != SD_EVENT_UNMUTED && !SD_EVENT_ONESHOT)
966 if (m == SD_EVENT_MUTED) {
971 r = source_io_unregister(s);
978 case SOURCE_MONOTONIC:
980 prioq_reshuffle(s->event->monotonic_earliest, s, &s->time.earliest_index);
981 prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
984 case SOURCE_REALTIME:
986 prioq_reshuffle(s->event->realtime_earliest, s, &s->time.earliest_index);
987 prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
992 if (s->signal.sig != SIGCHLD || s->event->n_unmuted_child_sources == 0) {
993 assert_se(sigdelset(&s->event->sigset, s->signal.sig) == 0);
994 event_update_signal_fd(s->event);
1002 assert(s->event->n_unmuted_child_sources > 0);
1003 s->event->n_unmuted_child_sources--;
1005 if (!s->event->signal_sources || !s->event->signal_sources[SIGCHLD]) {
1006 assert_se(sigdelset(&s->event->sigset, SIGCHLD) == 0);
1007 event_update_signal_fd(s->event);
1021 r = source_io_register(s, m, s->io.events);
1028 case SOURCE_MONOTONIC:
1030 prioq_reshuffle(s->event->monotonic_earliest, s, &s->time.earliest_index);
1031 prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
1034 case SOURCE_REALTIME:
1036 prioq_reshuffle(s->event->realtime_earliest, s, &s->time.earliest_index);
1037 prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
1043 if (s->signal.sig != SIGCHLD || s->event->n_unmuted_child_sources == 0) {
1044 assert_se(sigaddset(&s->event->sigset, s->signal.sig) == 0);
1045 event_update_signal_fd(s->event);
1052 if (s->mute == SD_EVENT_MUTED) {
1053 s->event->n_unmuted_child_sources++;
1055 if (!s->event->signal_sources || !s->event->signal_sources[SIGCHLD]) {
1056 assert_se(sigaddset(&s->event->sigset, SIGCHLD) == 0);
1057 event_update_signal_fd(s->event);
1069 prioq_reshuffle(s->event->pending, s, &s->pending_index);
1072 prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
1077 int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
1082 if (s->type != SOURCE_REALTIME && s->type != SOURCE_MONOTONIC)
1085 *usec = s->time.next;
1089 int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
1092 if (usec == (uint64_t) -1)
1094 if (s->type != SOURCE_REALTIME && s->type != SOURCE_MONOTONIC)
1097 if (s->time.next == usec)
1100 s->time.next = usec;
1102 if (s->type == SOURCE_REALTIME) {
1103 prioq_reshuffle(s->event->realtime_earliest, s, &s->time.earliest_index);
1104 prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
1106 prioq_reshuffle(s->event->monotonic_earliest, s, &s->time.earliest_index);
1107 prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
1113 int sd_event_source_set_prepare(sd_event_source *s, sd_prepare_handler_t callback) {
1119 if (s->prepare == callback)
1122 if (callback && s->prepare) {
1123 s->prepare = callback;
1127 r = prioq_ensure_allocated(&s->event->prepare, prepare_prioq_compare);
1131 s->prepare = callback;
1134 r = prioq_put(s->event->prepare, s, &s->prepare_index);
1138 prioq_remove(s->event->prepare, s, &s->prepare_index);
1143 void* sd_event_source_get_userdata(sd_event_source *s) {
1150 static usec_t sleep_between(sd_event *e, usec_t a, usec_t b) {
1162 Find a good time to wake up again between times a and b. We
1163 have two goals here:
1165 a) We want to wake up as seldom as possible, hence prefer
1166 later times over earlier times.
1168 b) But if we have to wake up, then let's make sure to
1169 dispatch as much as possible on the entire system.
1171 We implement this by waking up everywhere at the same time
1172 within any given second if we can, synchronised via the
1173 perturbation value determined from the boot ID. If we can't,
1174 then we try to find the same spot in every a 250ms
1175 step. Otherwise, we pick the last possible time to wake up.
1178 c = (b / USEC_PER_SEC) * USEC_PER_SEC + e->perturb;
1180 if (_unlikely_(c < USEC_PER_SEC))
1189 c = (b / (USEC_PER_MSEC*250)) * (USEC_PER_MSEC*250) + (e->perturb % (USEC_PER_MSEC*250));
1191 if (_unlikely_(c < USEC_PER_MSEC*250))
1194 c -= USEC_PER_MSEC*250;
1203 static int event_arm_timer(
1210 struct itimerspec its = {};
1211 sd_event_source *a, *b;
1218 a = prioq_peek(earliest);
1219 if (!a || a->mute == SD_EVENT_MUTED)
1222 b = prioq_peek(latest);
1223 assert_se(b && b->mute != SD_EVENT_MUTED);
1225 t = sleep_between(e, a->time.next, b->time.next + b->time.accuracy);
1229 assert_se(timer_fd >= 0);
1232 /* We don' want to disarm here, just mean some time looooong ago. */
1233 its.it_value.tv_sec = 0;
1234 its.it_value.tv_nsec = 1;
1236 timespec_store(&its.it_value, t);
1238 r = timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &its, NULL);
1246 static int process_io(sd_event *e, sd_event_source *s, uint32_t events) {
1249 assert(s->type == SOURCE_IO);
1251 s->io.revents = events;
1254 If this is a oneshot event source, then we added it to the
1255 epoll with EPOLLONESHOT, hence we know it's not registered
1256 anymore. We can save a syscall here...
1259 if (s->mute == SD_EVENT_ONESHOT)
1260 s->io.registered = false;
1262 return source_set_pending(s, true);
1265 static int flush_timer(sd_event *e, int fd, uint32_t events) {
1271 if (events != EPOLLIN)
1274 ss = read(fd, &x, sizeof(x));
1276 if (errno == EAGAIN || errno == EINTR)
1282 if (ss != sizeof(x))
1288 static int process_timer(sd_event *e, usec_t n, Prioq *earliest, Prioq *latest) {
1295 s = prioq_peek(earliest);
1298 s->mute == SD_EVENT_MUTED ||
1302 r = source_set_pending(s, true);
1306 prioq_reshuffle(earliest, s, &s->time.earliest_index);
1307 prioq_reshuffle(latest, s, &s->time.latest_index);
1313 static int process_child(sd_event *e) {
1320 e->need_process_child = false;
1323 So, this is ugly. We iteratively invoke waitid() with P_PID
1324 + WNOHANG for each PID we wait for, instead of using
1325 P_ALL. This is because we only want to get child
1326 information of very specific child processes, and not all
1327 of them. We might not have processed the SIGCHLD even of a
1328 previous invocation and we don't want to maintain a
1329 unbounded *per-child* event queue, hence we really don't
1330 want anything flushed out of the kernel's queue that we
1331 don't care about. Since this is O(n) this means that if you
1332 have a lot of processes you probably want to handle SIGCHLD
1336 HASHMAP_FOREACH(s, e->child_sources, i) {
1337 assert(s->type == SOURCE_CHILD);
1342 if (s->mute == SD_EVENT_MUTED)
1345 zero(s->child.siginfo);
1346 r = waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|s->child.options);
1350 if (s->child.siginfo.si_pid != 0) {
1351 r = source_set_pending(s, true);
1360 static int process_signal(sd_event *e, uint32_t events) {
1361 struct signalfd_siginfo si;
1362 bool read_one = false;
1366 if (events != EPOLLIN)
1372 ss = read(e->signal_fd, &si, sizeof(si));
1374 if (errno == EAGAIN || errno == EINTR)
1380 if (ss != sizeof(si))
1385 if (si.ssi_signo == SIGCHLD) {
1386 r = process_child(e);
1389 if (r > 0 || !e->signal_sources[si.ssi_signo])
1392 s = e->signal_sources[si.ssi_signo];
1397 s->signal.siginfo = si;
1398 r = source_set_pending(s, true);
1407 static int source_dispatch(sd_event_source *s) {
1413 r = source_set_pending(s, false);
1417 if (s->mute == SD_EVENT_ONESHOT) {
1418 r = sd_event_source_set_mute(s, SD_EVENT_MUTED);
1426 r = s->io.callback(s, s->io.fd, s->io.revents, s->userdata);
1429 case SOURCE_MONOTONIC:
1430 r = s->time.callback(s, s->time.next, s->userdata);
1433 case SOURCE_REALTIME:
1434 r = s->time.callback(s, s->time.next, s->userdata);
1438 r = s->signal.callback(s, &s->signal.siginfo, s->userdata);
1442 r = s->child.callback(s, &s->child.siginfo, s->userdata);
1446 r = s->defer.callback(s, s->userdata);
1453 static int event_prepare(sd_event *e) {
1461 s = prioq_peek(e->prepare);
1462 if (!s || s->prepare_iteration == e->iteration || s->mute == SD_EVENT_MUTED)
1465 s->prepare_iteration = e->iteration;
1466 r = prioq_reshuffle(e->prepare, s, &s->prepare_index);
1471 r = s->prepare(s, s->userdata);
1480 static sd_event_source* event_next_pending(sd_event *e) {
1483 p = prioq_peek(e->pending);
1487 if (p->mute == SD_EVENT_MUTED)
1493 int sd_event_run(sd_event *e, uint64_t timeout) {
1494 struct epoll_event ev_queue[EPOLL_QUEUE_MAX];
1506 r = event_prepare(e);
1510 if (event_next_pending(e) || e->need_process_child)
1514 r = event_arm_timer(e, e->monotonic_fd, e->monotonic_earliest, e->monotonic_latest, &e->monotonic_next);
1518 r = event_arm_timer(e, e->realtime_fd, e->realtime_earliest, e->realtime_latest, &e->realtime_next);
1523 m = epoll_wait(e->epoll_fd, ev_queue, EPOLL_QUEUE_MAX,
1524 timeout == (uint64_t) -1 ? -1 : (int) ((timeout + USEC_PER_MSEC - 1) / USEC_PER_MSEC));
1528 dual_timestamp_get(&n);
1530 for (i = 0; i < m; i++) {
1532 if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_MONOTONIC))
1533 r = flush_timer(e, e->monotonic_fd, ev_queue[i].events);
1534 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_REALTIME))
1535 r = flush_timer(e, e->realtime_fd, ev_queue[i].events);
1536 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_SIGNAL))
1537 r = process_signal(e, ev_queue[i].events);
1539 r = process_io(e, ev_queue[i].data.ptr, ev_queue[i].events);
1545 r = process_timer(e, n.monotonic, e->monotonic_earliest, e->monotonic_latest);
1549 r = process_timer(e, n.realtime, e->realtime_earliest, e->realtime_latest);
1553 if (e->need_process_child) {
1554 r = process_child(e);
1559 p = event_next_pending(e);
1563 return source_dispatch(p);
1566 int sd_event_loop(sd_event *e) {
1573 r = sd_event_run(e, (uint64_t) -1);
1581 int sd_event_quit(sd_event *e) {
1588 int sd_event_request_quit(sd_event *e) {
1596 sd_event *sd_event_get(sd_event_source *s) {
1603 int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) {
1606 if (s->type != SOURCE_MONOTONIC && s->type != SOURCE_REALTIME)
1610 usec = DEFAULT_ACCURACY_USEC;
1612 if (s->time.accuracy == usec)
1616 s->time.accuracy = usec;
1618 if (s->type == SOURCE_REALTIME)
1619 prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
1621 prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
1626 int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) {
1631 if (s->type != SOURCE_MONOTONIC && s->type != SOURCE_REALTIME)
1634 *usec = s->time.accuracy;