]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/sd-event.c
macro: clean up usage of gcc attributes
[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
26#include "macro.h"
fd38203a
LP
27#include "prioq.h"
28#include "hashmap.h"
29#include "util.h"
30#include "time-util.h"
c2ba3ad6 31#include "sd-id128.h"
fd38203a
LP
32
33#include "sd-event.h"
34
35#define EPOLL_QUEUE_MAX 64
c2ba3ad6 36#define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC)
fd38203a
LP
37
38typedef enum EventSourceType {
39 SOURCE_IO,
40 SOURCE_MONOTONIC,
41 SOURCE_REALTIME,
42 SOURCE_SIGNAL,
43 SOURCE_CHILD,
da7e457c
LP
44 SOURCE_DEFER,
45 SOURCE_QUIT
fd38203a
LP
46} EventSourceType;
47
48struct sd_event_source {
da7e457c 49 unsigned n_ref;
fd38203a
LP
50
51 sd_event *event;
52 void *userdata;
53 sd_prepare_handler_t prepare;
54
55 EventSourceType type:4;
baf76283 56 int enabled:3;
fd38203a
LP
57 bool pending:1;
58
59 int priority;
60 unsigned pending_index;
61 unsigned prepare_index;
62 unsigned pending_iteration;
63 unsigned prepare_iteration;
64
65 union {
66 struct {
67 sd_io_handler_t callback;
68 int fd;
69 uint32_t events;
70 uint32_t revents;
71 bool registered:1;
72 } io;
73 struct {
74 sd_time_handler_t callback;
c2ba3ad6
LP
75 usec_t next, accuracy;
76 unsigned earliest_index;
77 unsigned latest_index;
fd38203a
LP
78 } time;
79 struct {
80 sd_signal_handler_t callback;
81 struct signalfd_siginfo siginfo;
82 int sig;
83 } signal;
84 struct {
85 sd_child_handler_t callback;
86 siginfo_t siginfo;
87 pid_t pid;
88 int options;
89 } child;
90 struct {
91 sd_defer_handler_t callback;
92 } defer;
da7e457c
LP
93 struct {
94 sd_quit_handler_t callback;
95 unsigned prioq_index;
96 } quit;
fd38203a
LP
97 };
98};
99
100struct sd_event {
da7e457c 101 unsigned n_ref;
fd38203a
LP
102
103 int epoll_fd;
104 int signal_fd;
105 int realtime_fd;
106 int monotonic_fd;
107
108 Prioq *pending;
109 Prioq *prepare;
c2ba3ad6
LP
110
111 /* For both clocks we maintain two priority queues each, one
112 * ordered for the earliest times the events may be
113 * dispatched, and one ordered by the latest times they must
114 * have been dispatched. The range between the top entries in
115 * the two prioqs is the time window we can freely schedule
116 * wakeups in */
117 Prioq *monotonic_earliest;
118 Prioq *monotonic_latest;
119 Prioq *realtime_earliest;
120 Prioq *realtime_latest;
fd38203a 121
da7e457c
LP
122 usec_t realtime_next, monotonic_next;
123 usec_t perturb;
124
fd38203a
LP
125 sigset_t sigset;
126 sd_event_source **signal_sources;
127
128 Hashmap *child_sources;
baf76283 129 unsigned n_enabled_child_sources;
fd38203a 130
da7e457c 131 Prioq *quit;
fd38203a 132
da7e457c 133 pid_t original_pid;
c2ba3ad6 134
da7e457c 135 unsigned iteration;
46e8c825 136 dual_timestamp timestamp;
da7e457c 137 int state;
eaa3cbef 138
da7e457c
LP
139 bool quit_requested:1;
140 bool need_process_child:1;
fd38203a
LP
141};
142
143static int pending_prioq_compare(const void *a, const void *b) {
144 const sd_event_source *x = a, *y = b;
145
146 assert(x->pending);
147 assert(y->pending);
148
baf76283
LP
149 /* Enabled ones first */
150 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
fd38203a 151 return -1;
baf76283 152 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
fd38203a
LP
153 return 1;
154
155 /* Lower priority values first */
156 if (x->priority < y->priority)
157 return -1;
158 if (x->priority > y->priority)
159 return 1;
160
161 /* Older entries first */
162 if (x->pending_iteration < y->pending_iteration)
163 return -1;
164 if (x->pending_iteration > y->pending_iteration)
165 return 1;
166
167 /* Stability for the rest */
168 if (x < y)
169 return -1;
dfcd88f6 170 if (x > y)
fd38203a
LP
171 return 1;
172
173 return 0;
174}
175
176static int prepare_prioq_compare(const void *a, const void *b) {
177 const sd_event_source *x = a, *y = b;
178
179 assert(x->prepare);
180 assert(y->prepare);
181
182 /* Move most recently prepared ones last, so that we can stop
183 * preparing as soon as we hit one that has already been
184 * prepared in the current iteration */
185 if (x->prepare_iteration < y->prepare_iteration)
186 return -1;
187 if (x->prepare_iteration > y->prepare_iteration)
188 return 1;
189
baf76283
LP
190 /* Enabled ones first */
191 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
fd38203a 192 return -1;
baf76283 193 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
fd38203a
LP
194 return 1;
195
196 /* Lower priority values first */
197 if (x->priority < y->priority)
198 return -1;
199 if (x->priority > y->priority)
200 return 1;
201
202 /* Stability for the rest */
203 if (x < y)
204 return -1;
dfcd88f6 205 if (x > y)
fd38203a
LP
206 return 1;
207
208 return 0;
209}
210
c2ba3ad6 211static int earliest_time_prioq_compare(const void *a, const void *b) {
fd38203a
LP
212 const sd_event_source *x = a, *y = b;
213
214 assert(x->type == SOURCE_MONOTONIC || x->type == SOURCE_REALTIME);
215 assert(y->type == SOURCE_MONOTONIC || y->type == SOURCE_REALTIME);
216
baf76283
LP
217 /* Enabled ones first */
218 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
fd38203a 219 return -1;
baf76283 220 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
fd38203a
LP
221 return 1;
222
223 /* Move the pending ones to the end */
224 if (!x->pending && y->pending)
225 return -1;
226 if (x->pending && !y->pending)
227 return 1;
228
229 /* Order by time */
230 if (x->time.next < y->time.next)
231 return -1;
232 if (x->time.next > y->time.next)
233 return -1;
234
235 /* Stability for the rest */
236 if (x < y)
237 return -1;
dfcd88f6 238 if (x > y)
fd38203a
LP
239 return 1;
240
241 return 0;
242}
243
c2ba3ad6
LP
244static int latest_time_prioq_compare(const void *a, const void *b) {
245 const sd_event_source *x = a, *y = b;
246
da7e457c
LP
247 assert((x->type == SOURCE_MONOTONIC && y->type == SOURCE_MONOTONIC) ||
248 (x->type == SOURCE_REALTIME && y->type == SOURCE_REALTIME));
c2ba3ad6 249
baf76283
LP
250 /* Enabled ones first */
251 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
c2ba3ad6 252 return -1;
baf76283 253 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
c2ba3ad6
LP
254 return 1;
255
256 /* Move the pending ones to the end */
257 if (!x->pending && y->pending)
258 return -1;
259 if (x->pending && !y->pending)
260 return 1;
261
262 /* Order by time */
263 if (x->time.next + x->time.accuracy < y->time.next + y->time.accuracy)
264 return -1;
265 if (x->time.next + x->time.accuracy > y->time.next + y->time.accuracy)
266 return -1;
267
268 /* Stability for the rest */
269 if (x < y)
270 return -1;
271 if (x > y)
272 return 1;
273
274 return 0;
275}
276
da7e457c
LP
277static int quit_prioq_compare(const void *a, const void *b) {
278 const sd_event_source *x = a, *y = b;
279
280 assert(x->type == SOURCE_QUIT);
281 assert(y->type == SOURCE_QUIT);
282
baf76283
LP
283 /* Enabled ones first */
284 if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
da7e457c 285 return -1;
baf76283 286 if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
da7e457c
LP
287 return 1;
288
289 /* Lower priority values first */
290 if (x->priority < y->priority)
291 return -1;
292 if (x->priority > y->priority)
293 return 1;
294
295 /* Stability for the rest */
296 if (x < y)
297 return -1;
298 if (x > y)
299 return 1;
300
301 return 0;
302}
303
fd38203a
LP
304static void event_free(sd_event *e) {
305 assert(e);
306
307 if (e->epoll_fd >= 0)
308 close_nointr_nofail(e->epoll_fd);
309
310 if (e->signal_fd >= 0)
311 close_nointr_nofail(e->signal_fd);
312
313 if (e->realtime_fd >= 0)
314 close_nointr_nofail(e->realtime_fd);
315
316 if (e->monotonic_fd >= 0)
317 close_nointr_nofail(e->monotonic_fd);
318
319 prioq_free(e->pending);
320 prioq_free(e->prepare);
c2ba3ad6
LP
321 prioq_free(e->monotonic_earliest);
322 prioq_free(e->monotonic_latest);
323 prioq_free(e->realtime_earliest);
324 prioq_free(e->realtime_latest);
da7e457c 325 prioq_free(e->quit);
fd38203a
LP
326
327 free(e->signal_sources);
328
329 hashmap_free(e->child_sources);
330 free(e);
331}
332
333int sd_event_new(sd_event** ret) {
334 sd_event *e;
335 int r;
336
305f78bf 337 assert_return(ret, -EINVAL);
fd38203a
LP
338
339 e = new0(sd_event, 1);
340 if (!e)
341 return -ENOMEM;
342
da7e457c 343 e->n_ref = 1;
fd38203a
LP
344 e->signal_fd = e->realtime_fd = e->monotonic_fd = e->epoll_fd = -1;
345 e->realtime_next = e->monotonic_next = (usec_t) -1;
eaa3cbef 346 e->original_pid = getpid();
fd38203a
LP
347
348 assert_se(sigemptyset(&e->sigset) == 0);
349
350 e->pending = prioq_new(pending_prioq_compare);
351 if (!e->pending) {
352 r = -ENOMEM;
353 goto fail;
354 }
355
356 e->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
357 if (e->epoll_fd < 0) {
358 r = -errno;
359 goto fail;
360 }
361
362 *ret = e;
363 return 0;
364
365fail:
366 event_free(e);
367 return r;
368}
369
370sd_event* sd_event_ref(sd_event *e) {
305f78bf 371 assert_return(e, NULL);
fd38203a 372
da7e457c
LP
373 assert(e->n_ref >= 1);
374 e->n_ref++;
fd38203a
LP
375
376 return e;
377}
378
379sd_event* sd_event_unref(sd_event *e) {
305f78bf 380 assert_return(e, NULL);
fd38203a 381
da7e457c
LP
382 assert(e->n_ref >= 1);
383 e->n_ref--;
384
385 if (e->n_ref <= 0)
fd38203a
LP
386 event_free(e);
387
388 return NULL;
389}
390
eaa3cbef
LP
391static bool event_pid_changed(sd_event *e) {
392 assert(e);
393
394 /* We don't support people creating am event loop and keeping
395 * it around over a fork(). Let's complain. */
396
397 return e->original_pid != getpid();
398}
399
fd38203a
LP
400static int source_io_unregister(sd_event_source *s) {
401 int r;
402
403 assert(s);
404 assert(s->type == SOURCE_IO);
405
406 if (!s->io.registered)
407 return 0;
408
409 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, s->io.fd, NULL);
410 if (r < 0)
411 return -errno;
412
413 s->io.registered = false;
414 return 0;
415}
416
305f78bf
LP
417static int source_io_register(
418 sd_event_source *s,
419 int enabled,
420 uint32_t events) {
421
fd38203a
LP
422 struct epoll_event ev = {};
423 int r;
424
425 assert(s);
426 assert(s->type == SOURCE_IO);
baf76283 427 assert(enabled != SD_EVENT_OFF);
fd38203a
LP
428
429 ev.events = events;
430 ev.data.ptr = s;
431
baf76283 432 if (enabled == SD_EVENT_ONESHOT)
fd38203a
LP
433 ev.events |= EPOLLONESHOT;
434
435 if (s->io.registered)
436 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_MOD, s->io.fd, &ev);
437 else
438 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_ADD, s->io.fd, &ev);
439
440 if (r < 0)
441 return -errno;
442
443 s->io.registered = true;
444
445 return 0;
446}
447
448static void source_free(sd_event_source *s) {
449 assert(s);
450
451 if (s->event) {
452 switch (s->type) {
453
454 case SOURCE_IO:
455 if (s->io.fd >= 0)
456 source_io_unregister(s);
457
458 break;
459
460 case SOURCE_MONOTONIC:
c2ba3ad6
LP
461 prioq_remove(s->event->monotonic_earliest, s, &s->time.earliest_index);
462 prioq_remove(s->event->monotonic_latest, s, &s->time.latest_index);
fd38203a
LP
463 break;
464
465 case SOURCE_REALTIME:
c2ba3ad6
LP
466 prioq_remove(s->event->realtime_earliest, s, &s->time.earliest_index);
467 prioq_remove(s->event->realtime_latest, s, &s->time.latest_index);
fd38203a
LP
468 break;
469
470 case SOURCE_SIGNAL:
471 if (s->signal.sig > 0) {
baf76283 472 if (s->signal.sig != SIGCHLD || s->event->n_enabled_child_sources == 0)
fd38203a
LP
473 assert_se(sigdelset(&s->event->sigset, s->signal.sig) == 0);
474
475 if (s->event->signal_sources)
476 s->event->signal_sources[s->signal.sig] = NULL;
477 }
478
479 break;
480
481 case SOURCE_CHILD:
482 if (s->child.pid > 0) {
baf76283
LP
483 if (s->enabled != SD_EVENT_OFF) {
484 assert(s->event->n_enabled_child_sources > 0);
485 s->event->n_enabled_child_sources--;
fd38203a
LP
486 }
487
488 if (!s->event->signal_sources || !s->event->signal_sources[SIGCHLD])
489 assert_se(sigdelset(&s->event->sigset, SIGCHLD) == 0);
490
491 hashmap_remove(s->event->child_sources, INT_TO_PTR(s->child.pid));
492 }
493
494 break;
da7e457c 495
0eb2e0e3
ZJS
496 case SOURCE_DEFER:
497 /* nothing */
498 break;
499
da7e457c
LP
500 case SOURCE_QUIT:
501 prioq_remove(s->event->quit, s, &s->quit.prioq_index);
502 break;
fd38203a
LP
503 }
504
505 if (s->pending)
506 prioq_remove(s->event->pending, s, &s->pending_index);
507
508 if (s->prepare)
509 prioq_remove(s->event->prepare, s, &s->prepare_index);
510
511 sd_event_unref(s->event);
512 }
513
514 free(s);
515}
516
517static int source_set_pending(sd_event_source *s, bool b) {
518 int r;
519
520 assert(s);
da7e457c 521 assert(s->type != SOURCE_QUIT);
fd38203a
LP
522
523 if (s->pending == b)
524 return 0;
525
526 s->pending = b;
527
528 if (b) {
529 s->pending_iteration = s->event->iteration;
530
531 r = prioq_put(s->event->pending, s, &s->pending_index);
532 if (r < 0) {
533 s->pending = false;
534 return r;
535 }
536 } else
537 assert_se(prioq_remove(s->event->pending, s, &s->pending_index));
538
539 return 0;
540}
541
542static sd_event_source *source_new(sd_event *e, EventSourceType type) {
543 sd_event_source *s;
544
545 assert(e);
546
547 s = new0(sd_event_source, 1);
548 if (!s)
549 return NULL;
550
da7e457c 551 s->n_ref = 1;
fd38203a
LP
552 s->event = sd_event_ref(e);
553 s->type = type;
fd38203a
LP
554 s->pending_index = s->prepare_index = PRIOQ_IDX_NULL;
555
556 return s;
557}
558
559int sd_event_add_io(
560 sd_event *e,
561 int fd,
562 uint32_t events,
563 sd_io_handler_t callback,
564 void *userdata,
565 sd_event_source **ret) {
566
567 sd_event_source *s;
568 int r;
569
305f78bf
LP
570 assert_return(e, -EINVAL);
571 assert_return(fd >= 0, -EINVAL);
572 assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP)), -EINVAL);
573 assert_return(callback, -EINVAL);
574 assert_return(ret, -EINVAL);
da7e457c 575 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 576 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a
LP
577
578 s = source_new(e, SOURCE_IO);
579 if (!s)
580 return -ENOMEM;
581
582 s->io.fd = fd;
583 s->io.events = events;
584 s->io.callback = callback;
585 s->userdata = userdata;
baf76283 586 s->enabled = SD_EVENT_ON;
fd38203a 587
baf76283 588 r = source_io_register(s, s->enabled, events);
fd38203a
LP
589 if (r < 0) {
590 source_free(s);
591 return -errno;
592 }
593
594 *ret = s;
595 return 0;
596}
597
598static int event_setup_timer_fd(
599 sd_event *e,
600 EventSourceType type,
601 int *timer_fd,
602 clockid_t id) {
603
604 struct epoll_event ev = {};
605 int r, fd;
c2ba3ad6 606 sd_id128_t bootid;
fd38203a
LP
607
608 assert(e);
609 assert(timer_fd);
610
611 if (_likely_(*timer_fd >= 0))
612 return 0;
613
614 fd = timerfd_create(id, TFD_NONBLOCK|TFD_CLOEXEC);
615 if (fd < 0)
616 return -errno;
617
618 ev.events = EPOLLIN;
619 ev.data.ptr = INT_TO_PTR(type);
620
621 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, fd, &ev);
622 if (r < 0) {
623 close_nointr_nofail(fd);
624 return -errno;
625 }
626
c2ba3ad6
LP
627 /* When we sleep for longer, we try to realign the wakeup to
628 the same time wihtin each second, so that events all across
629 the system can be coalesced into a single CPU
630 wakeup. However, let's take some system-specific randomness
631 for this value, so that in a network of systems with synced
632 clocks timer events are distributed a bit. Here, we
633 calculate a perturbation usec offset from the boot ID. */
634
635 if (sd_id128_get_boot(&bootid) >= 0)
636 e->perturb = (bootid.qwords[0] ^ bootid.qwords[1]) % USEC_PER_SEC;
637
fd38203a
LP
638 *timer_fd = fd;
639 return 0;
640}
641
642static int event_add_time_internal(
643 sd_event *e,
644 EventSourceType type,
645 int *timer_fd,
646 clockid_t id,
c2ba3ad6
LP
647 Prioq **earliest,
648 Prioq **latest,
fd38203a 649 uint64_t usec,
c2ba3ad6 650 uint64_t accuracy,
fd38203a
LP
651 sd_time_handler_t callback,
652 void *userdata,
653 sd_event_source **ret) {
654
655 sd_event_source *s;
656 int r;
657
305f78bf
LP
658 assert_return(e, -EINVAL);
659 assert_return(callback, -EINVAL);
660 assert_return(ret, -EINVAL);
661 assert_return(usec != (uint64_t) -1, -EINVAL);
662 assert_return(accuracy != (uint64_t) -1, -EINVAL);
da7e457c 663 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 664 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a
LP
665
666 assert(timer_fd);
c2ba3ad6
LP
667 assert(earliest);
668 assert(latest);
669
670 if (!*earliest) {
671 *earliest = prioq_new(earliest_time_prioq_compare);
672 if (!*earliest)
673 return -ENOMEM;
674 }
fd38203a 675
c2ba3ad6
LP
676 if (!*latest) {
677 *latest = prioq_new(latest_time_prioq_compare);
678 if (!*latest)
fd38203a
LP
679 return -ENOMEM;
680 }
681
682 if (*timer_fd < 0) {
683 r = event_setup_timer_fd(e, type, timer_fd, id);
684 if (r < 0)
685 return r;
686 }
687
688 s = source_new(e, type);
689 if (!s)
690 return -ENOMEM;
691
692 s->time.next = usec;
c2ba3ad6 693 s->time.accuracy = accuracy == 0 ? DEFAULT_ACCURACY_USEC : accuracy;
fd38203a 694 s->time.callback = callback;
da7e457c 695 s->time.earliest_index = s->time.latest_index = PRIOQ_IDX_NULL;
fd38203a 696 s->userdata = userdata;
baf76283 697 s->enabled = SD_EVENT_ONESHOT;
fd38203a 698
c2ba3ad6
LP
699 r = prioq_put(*earliest, s, &s->time.earliest_index);
700 if (r < 0)
701 goto fail;
702
703 r = prioq_put(*latest, s, &s->time.latest_index);
704 if (r < 0)
705 goto fail;
fd38203a
LP
706
707 *ret = s;
708 return 0;
c2ba3ad6
LP
709
710fail:
711 source_free(s);
712 return r;
fd38203a
LP
713}
714
c2ba3ad6
LP
715int sd_event_add_monotonic(sd_event *e, uint64_t usec, uint64_t accuracy, sd_time_handler_t callback, void *userdata, sd_event_source **ret) {
716 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
717}
718
c2ba3ad6
LP
719int sd_event_add_realtime(sd_event *e, uint64_t usec, uint64_t accuracy, sd_time_handler_t callback, void *userdata, sd_event_source **ret) {
720 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
721}
722
723static int event_update_signal_fd(sd_event *e) {
724 struct epoll_event ev = {};
725 bool add_to_epoll;
726 int r;
727
728 assert(e);
729
730 add_to_epoll = e->signal_fd < 0;
731
732 r = signalfd(e->signal_fd, &e->sigset, SFD_NONBLOCK|SFD_CLOEXEC);
733 if (r < 0)
734 return -errno;
735
736 e->signal_fd = r;
737
738 if (!add_to_epoll)
739 return 0;
740
741 ev.events = EPOLLIN;
742 ev.data.ptr = INT_TO_PTR(SOURCE_SIGNAL);
743
744 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, e->signal_fd, &ev);
745 if (r < 0) {
746 close_nointr_nofail(e->signal_fd);
747 e->signal_fd = -1;
748
749 return -errno;
750 }
751
752 return 0;
753}
754
305f78bf
LP
755int sd_event_add_signal(
756 sd_event *e,
757 int sig,
758 sd_signal_handler_t callback,
759 void *userdata,
760 sd_event_source **ret) {
761
fd38203a
LP
762 sd_event_source *s;
763 int r;
764
305f78bf
LP
765 assert_return(e, -EINVAL);
766 assert_return(sig > 0, -EINVAL);
767 assert_return(sig < _NSIG, -EINVAL);
768 assert_return(callback, -EINVAL);
769 assert_return(ret, -EINVAL);
da7e457c 770 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 771 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a
LP
772
773 if (!e->signal_sources) {
774 e->signal_sources = new0(sd_event_source*, _NSIG);
775 if (!e->signal_sources)
776 return -ENOMEM;
777 } else if (e->signal_sources[sig])
778 return -EBUSY;
779
780 s = source_new(e, SOURCE_SIGNAL);
781 if (!s)
782 return -ENOMEM;
783
784 s->signal.sig = sig;
785 s->signal.callback = callback;
786 s->userdata = userdata;
baf76283 787 s->enabled = SD_EVENT_ON;
fd38203a
LP
788
789 e->signal_sources[sig] = s;
790 assert_se(sigaddset(&e->sigset, sig) == 0);
791
baf76283 792 if (sig != SIGCHLD || e->n_enabled_child_sources == 0) {
fd38203a
LP
793 r = event_update_signal_fd(e);
794 if (r < 0) {
795 source_free(s);
796 return r;
797 }
798 }
799
800 *ret = s;
801 return 0;
802}
803
305f78bf
LP
804int sd_event_add_child(
805 sd_event *e,
806 pid_t pid,
807 int options,
808 sd_child_handler_t callback,
809 void *userdata,
810 sd_event_source **ret) {
811
fd38203a
LP
812 sd_event_source *s;
813 int r;
814
305f78bf
LP
815 assert_return(e, -EINVAL);
816 assert_return(pid > 1, -EINVAL);
817 assert_return(!(options & ~(WEXITED|WSTOPPED|WCONTINUED)), -EINVAL);
818 assert_return(options != 0, -EINVAL);
819 assert_return(callback, -EINVAL);
820 assert_return(ret, -EINVAL);
da7e457c 821 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 822 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a
LP
823
824 r = hashmap_ensure_allocated(&e->child_sources, trivial_hash_func, trivial_compare_func);
825 if (r < 0)
826 return r;
827
828 if (hashmap_contains(e->child_sources, INT_TO_PTR(pid)))
829 return -EBUSY;
830
831 s = source_new(e, SOURCE_CHILD);
832 if (!s)
833 return -ENOMEM;
834
835 s->child.pid = pid;
836 s->child.options = options;
837 s->child.callback = callback;
838 s->userdata = userdata;
baf76283 839 s->enabled = SD_EVENT_ONESHOT;
fd38203a
LP
840
841 r = hashmap_put(e->child_sources, INT_TO_PTR(pid), s);
842 if (r < 0) {
843 source_free(s);
844 return r;
845 }
846
baf76283 847 e->n_enabled_child_sources ++;
fd38203a
LP
848
849 assert_se(sigaddset(&e->sigset, SIGCHLD) == 0);
850
851 if (!e->signal_sources || !e->signal_sources[SIGCHLD]) {
852 r = event_update_signal_fd(e);
853 if (r < 0) {
854 source_free(s);
855 return -errno;
856 }
857 }
858
c2ba3ad6
LP
859 e->need_process_child = true;
860
fd38203a
LP
861 *ret = s;
862 return 0;
863}
864
305f78bf
LP
865int sd_event_add_defer(
866 sd_event *e,
867 sd_defer_handler_t callback,
868 void *userdata,
869 sd_event_source **ret) {
870
fd38203a
LP
871 sd_event_source *s;
872 int r;
873
305f78bf
LP
874 assert_return(e, -EINVAL);
875 assert_return(callback, -EINVAL);
876 assert_return(ret, -EINVAL);
da7e457c 877 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 878 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a
LP
879
880 s = source_new(e, SOURCE_DEFER);
881 if (!s)
882 return -ENOMEM;
883
884 s->defer.callback = callback;
885 s->userdata = userdata;
baf76283 886 s->enabled = SD_EVENT_ONESHOT;
fd38203a
LP
887
888 r = source_set_pending(s, true);
889 if (r < 0) {
890 source_free(s);
891 return r;
892 }
893
894 *ret = s;
895 return 0;
896}
897
305f78bf
LP
898int sd_event_add_quit(
899 sd_event *e,
900 sd_quit_handler_t callback,
901 void *userdata,
902 sd_event_source **ret) {
903
da7e457c
LP
904 sd_event_source *s;
905 int r;
906
907 assert_return(e, -EINVAL);
908 assert_return(callback, -EINVAL);
305f78bf 909 assert_return(ret, -EINVAL);
da7e457c
LP
910 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
911 assert_return(!event_pid_changed(e), -ECHILD);
912
913 if (!e->quit) {
914 e->quit = prioq_new(quit_prioq_compare);
915 if (!e->quit)
916 return -ENOMEM;
917 }
918
919 s = source_new(e, SOURCE_QUIT);
fd38203a 920 if (!s)
da7e457c 921 return -ENOMEM;
fd38203a 922
da7e457c
LP
923 s->quit.callback = callback;
924 s->userdata = userdata;
925 s->quit.prioq_index = PRIOQ_IDX_NULL;
baf76283 926 s->enabled = SD_EVENT_ONESHOT;
da7e457c
LP
927
928 r = prioq_put(s->event->quit, s, &s->quit.prioq_index);
929 if (r < 0) {
930 source_free(s);
931 return r;
932 }
933
934 *ret = s;
935 return 0;
936}
937
938sd_event_source* sd_event_source_ref(sd_event_source *s) {
939 assert_return(s, NULL);
940
941 assert(s->n_ref >= 1);
942 s->n_ref++;
fd38203a
LP
943
944 return s;
945}
946
947sd_event_source* sd_event_source_unref(sd_event_source *s) {
da7e457c 948 assert_return(s, NULL);
fd38203a 949
da7e457c
LP
950 assert(s->n_ref >= 1);
951 s->n_ref--;
952
953 if (s->n_ref <= 0)
fd38203a
LP
954 source_free(s);
955
956 return NULL;
957}
958
eaa3cbef 959sd_event *sd_event_get(sd_event_source *s) {
305f78bf 960 assert_return(s, NULL);
eaa3cbef
LP
961
962 return s->event;
963}
964
fd38203a 965int sd_event_source_get_pending(sd_event_source *s) {
305f78bf
LP
966 assert_return(s, -EINVAL);
967 assert_return(s->type != SOURCE_QUIT, -EDOM);
da7e457c 968 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 969 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
970
971 return s->pending;
972}
973
974int sd_event_source_get_io_fd(sd_event_source *s) {
305f78bf
LP
975 assert_return(s, -EINVAL);
976 assert_return(s->type == SOURCE_IO, -EDOM);
977 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
978
979 return s->io.fd;
980}
981
982int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) {
305f78bf
LP
983 assert_return(s, -EINVAL);
984 assert_return(events, -EINVAL);
985 assert_return(s->type == SOURCE_IO, -EDOM);
986 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
987
988 *events = s->io.events;
989 return 0;
990}
991
992int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) {
993 int r;
994
305f78bf
LP
995 assert_return(s, -EINVAL);
996 assert_return(s->type == SOURCE_IO, -EDOM);
997 assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP)), -EINVAL);
da7e457c 998 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 999 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1000
1001 if (s->io.events == events)
1002 return 0;
1003
baf76283 1004 if (s->enabled != SD_EVENT_OFF) {
fd38203a
LP
1005 r = source_io_register(s, s->io.events, events);
1006 if (r < 0)
1007 return r;
1008 }
1009
1010 s->io.events = events;
1011
1012 return 0;
1013}
1014
1015int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents) {
305f78bf
LP
1016 assert_return(s, -EINVAL);
1017 assert_return(revents, -EINVAL);
1018 assert_return(s->type == SOURCE_IO, -EDOM);
1019 assert_return(s->pending, -ENODATA);
1020 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1021
1022 *revents = s->io.revents;
1023 return 0;
1024}
1025
1026int sd_event_source_get_signal(sd_event_source *s) {
305f78bf
LP
1027 assert_return(s, -EINVAL);
1028 assert_return(s->type == SOURCE_SIGNAL, -EDOM);
1029 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1030
1031 return s->signal.sig;
1032}
1033
1034int sd_event_source_get_priority(sd_event_source *s, int *priority) {
305f78bf
LP
1035 assert_return(s, -EINVAL);
1036 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1037
1038 return s->priority;
1039}
1040
1041int sd_event_source_set_priority(sd_event_source *s, int priority) {
305f78bf 1042 assert_return(s, -EINVAL);
da7e457c 1043 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1044 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1045
1046 if (s->priority == priority)
1047 return 0;
1048
1049 s->priority = priority;
1050
1051 if (s->pending)
c2ba3ad6 1052 prioq_reshuffle(s->event->pending, s, &s->pending_index);
fd38203a
LP
1053
1054 if (s->prepare)
c2ba3ad6 1055 prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
fd38203a 1056
305f78bf
LP
1057 if (s->type == SOURCE_QUIT)
1058 prioq_reshuffle(s->event->quit, s, &s->quit.prioq_index);
1059
fd38203a
LP
1060 return 0;
1061}
1062
baf76283 1063int sd_event_source_get_enabled(sd_event_source *s, int *m) {
305f78bf
LP
1064 assert_return(s, -EINVAL);
1065 assert_return(m, -EINVAL);
1066 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a 1067
baf76283 1068 *m = s->enabled;
fd38203a
LP
1069 return 0;
1070}
1071
baf76283 1072int sd_event_source_set_enabled(sd_event_source *s, int m) {
fd38203a
LP
1073 int r;
1074
305f78bf
LP
1075 assert_return(s, -EINVAL);
1076 assert_return(m == SD_EVENT_OFF || m == SD_EVENT_ON || m == SD_EVENT_ONESHOT, -EINVAL);
da7e457c 1077 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1078 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a 1079
baf76283 1080 if (s->enabled == m)
fd38203a
LP
1081 return 0;
1082
baf76283 1083 if (m == SD_EVENT_OFF) {
fd38203a
LP
1084
1085 switch (s->type) {
1086
1087 case SOURCE_IO:
1088 r = source_io_unregister(s);
1089 if (r < 0)
1090 return r;
1091
baf76283 1092 s->enabled = m;
fd38203a
LP
1093 break;
1094
1095 case SOURCE_MONOTONIC:
baf76283 1096 s->enabled = m;
c2ba3ad6
LP
1097 prioq_reshuffle(s->event->monotonic_earliest, s, &s->time.earliest_index);
1098 prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
fd38203a
LP
1099 break;
1100
1101 case SOURCE_REALTIME:
baf76283 1102 s->enabled = m;
c2ba3ad6
LP
1103 prioq_reshuffle(s->event->realtime_earliest, s, &s->time.earliest_index);
1104 prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
fd38203a
LP
1105 break;
1106
1107 case SOURCE_SIGNAL:
baf76283
LP
1108 s->enabled = m;
1109 if (s->signal.sig != SIGCHLD || s->event->n_enabled_child_sources == 0) {
fd38203a
LP
1110 assert_se(sigdelset(&s->event->sigset, s->signal.sig) == 0);
1111 event_update_signal_fd(s->event);
1112 }
1113
1114 break;
1115
1116 case SOURCE_CHILD:
baf76283 1117 s->enabled = m;
fd38203a 1118
baf76283
LP
1119 assert(s->event->n_enabled_child_sources > 0);
1120 s->event->n_enabled_child_sources--;
fd38203a
LP
1121
1122 if (!s->event->signal_sources || !s->event->signal_sources[SIGCHLD]) {
1123 assert_se(sigdelset(&s->event->sigset, SIGCHLD) == 0);
1124 event_update_signal_fd(s->event);
1125 }
1126
1127 break;
1128
da7e457c 1129 case SOURCE_QUIT:
305f78bf
LP
1130 s->enabled = m;
1131 prioq_reshuffle(s->event->quit, s, &s->quit.prioq_index);
1132 break;
1133
1134 case SOURCE_DEFER:
baf76283 1135 s->enabled = m;
fd38203a
LP
1136 break;
1137 }
1138
1139 } else {
1140 switch (s->type) {
1141
1142 case SOURCE_IO:
1143 r = source_io_register(s, m, s->io.events);
1144 if (r < 0)
1145 return r;
1146
baf76283 1147 s->enabled = m;
fd38203a
LP
1148 break;
1149
1150 case SOURCE_MONOTONIC:
baf76283 1151 s->enabled = m;
c2ba3ad6
LP
1152 prioq_reshuffle(s->event->monotonic_earliest, s, &s->time.earliest_index);
1153 prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
fd38203a
LP
1154 break;
1155
1156 case SOURCE_REALTIME:
baf76283 1157 s->enabled = m;
c2ba3ad6
LP
1158 prioq_reshuffle(s->event->realtime_earliest, s, &s->time.earliest_index);
1159 prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
fd38203a
LP
1160 break;
1161
1162 case SOURCE_SIGNAL:
baf76283 1163 s->enabled = m;
fd38203a 1164
baf76283 1165 if (s->signal.sig != SIGCHLD || s->event->n_enabled_child_sources == 0) {
fd38203a
LP
1166 assert_se(sigaddset(&s->event->sigset, s->signal.sig) == 0);
1167 event_update_signal_fd(s->event);
1168 }
1169 break;
1170
1171 case SOURCE_CHILD:
baf76283 1172 s->enabled = m;
fd38203a 1173
baf76283
LP
1174 if (s->enabled == SD_EVENT_OFF) {
1175 s->event->n_enabled_child_sources++;
fd38203a
LP
1176
1177 if (!s->event->signal_sources || !s->event->signal_sources[SIGCHLD]) {
1178 assert_se(sigaddset(&s->event->sigset, SIGCHLD) == 0);
1179 event_update_signal_fd(s->event);
1180 }
1181 }
1182 break;
1183
da7e457c 1184 case SOURCE_QUIT:
305f78bf
LP
1185 s->enabled = m;
1186 prioq_reshuffle(s->event->quit, s, &s->quit.prioq_index);
1187 break;
1188
1189 case SOURCE_DEFER:
baf76283 1190 s->enabled = m;
fd38203a
LP
1191 break;
1192 }
1193 }
1194
1195 if (s->pending)
1196 prioq_reshuffle(s->event->pending, s, &s->pending_index);
1197
1198 if (s->prepare)
1199 prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
1200
1201 return 0;
1202}
1203
1204int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
305f78bf
LP
1205 assert_return(s, -EINVAL);
1206 assert_return(usec, -EINVAL);
1207 assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM);
1208 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1209
1210 *usec = s->time.next;
1211 return 0;
1212}
1213
1214int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
305f78bf
LP
1215 assert_return(s, -EINVAL);
1216 assert_return(usec != (uint64_t) -1, -EINVAL);
1217 assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM);
da7e457c 1218 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1219 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1220
1221 if (s->time.next == usec)
1222 return 0;
1223
1224 s->time.next = usec;
1225
c2ba3ad6
LP
1226 if (s->type == SOURCE_REALTIME) {
1227 prioq_reshuffle(s->event->realtime_earliest, s, &s->time.earliest_index);
1228 prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
1229 } else {
1230 prioq_reshuffle(s->event->monotonic_earliest, s, &s->time.earliest_index);
1231 prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
1232 }
fd38203a
LP
1233
1234 return 0;
1235}
1236
305f78bf
LP
1237int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) {
1238 assert_return(s, -EINVAL);
1239 assert_return(usec, -EINVAL);
1240 assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM);
1241 assert_return(!event_pid_changed(s->event), -ECHILD);
1242
1243 *usec = s->time.accuracy;
1244 return 0;
1245}
1246
eaa3cbef 1247int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) {
305f78bf
LP
1248 assert_return(s, -EINVAL);
1249 assert_return(usec != (uint64_t) -1, -EINVAL);
1250 assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM);
da7e457c 1251 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
305f78bf 1252 assert_return(!event_pid_changed(s->event), -ECHILD);
eaa3cbef
LP
1253
1254 if (usec == 0)
1255 usec = DEFAULT_ACCURACY_USEC;
1256
1257 if (s->time.accuracy == usec)
1258 return 0;
1259
eaa3cbef
LP
1260 s->time.accuracy = usec;
1261
1262 if (s->type == SOURCE_REALTIME)
1263 prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
1264 else
1265 prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
1266
1267 return 0;
1268}
1269
4bee8012
LP
1270int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) {
1271 assert_return(s, -EINVAL);
1272 assert_return(pid, -EINVAL);
1273 assert_return(s->type == SOURCE_CHILD, -EDOM);
1274 assert_return(!event_pid_changed(s->event), -ECHILD);
1275
1276 *pid = s->child.pid;
1277 return 0;
1278}
1279
fd38203a
LP
1280int sd_event_source_set_prepare(sd_event_source *s, sd_prepare_handler_t callback) {
1281 int r;
1282
da7e457c
LP
1283 assert_return(s, -EINVAL);
1284 assert_return(s->type != SOURCE_QUIT, -EDOM);
1285 assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
1286 assert_return(!event_pid_changed(s->event), -ECHILD);
fd38203a
LP
1287
1288 if (s->prepare == callback)
1289 return 0;
1290
1291 if (callback && s->prepare) {
1292 s->prepare = callback;
1293 return 0;
1294 }
1295
1296 r = prioq_ensure_allocated(&s->event->prepare, prepare_prioq_compare);
1297 if (r < 0)
1298 return r;
1299
1300 s->prepare = callback;
1301
1302 if (callback) {
1303 r = prioq_put(s->event->prepare, s, &s->prepare_index);
1304 if (r < 0)
1305 return r;
1306 } else
1307 prioq_remove(s->event->prepare, s, &s->prepare_index);
1308
1309 return 0;
1310}
1311
1312void* sd_event_source_get_userdata(sd_event_source *s) {
da7e457c 1313 assert_return(s, NULL);
fd38203a
LP
1314
1315 return s->userdata;
1316}
1317
c2ba3ad6
LP
1318static usec_t sleep_between(sd_event *e, usec_t a, usec_t b) {
1319 usec_t c;
1320 assert(e);
1321 assert(a <= b);
1322
1323 if (a <= 0)
1324 return 0;
1325
1326 if (b <= a + 1)
1327 return a;
1328
1329 /*
1330 Find a good time to wake up again between times a and b. We
1331 have two goals here:
1332
1333 a) We want to wake up as seldom as possible, hence prefer
1334 later times over earlier times.
1335
1336 b) But if we have to wake up, then let's make sure to
1337 dispatch as much as possible on the entire system.
1338
1339 We implement this by waking up everywhere at the same time
1340 within any given second if we can, synchronised via the
1341 perturbation value determined from the boot ID. If we can't,
1342 then we try to find the same spot in every a 250ms
1343 step. Otherwise, we pick the last possible time to wake up.
1344 */
1345
1346 c = (b / USEC_PER_SEC) * USEC_PER_SEC + e->perturb;
1347 if (c >= b) {
1348 if (_unlikely_(c < USEC_PER_SEC))
1349 return b;
1350
1351 c -= USEC_PER_SEC;
1352 }
1353
1354 if (c >= a)
1355 return c;
1356
1357 c = (b / (USEC_PER_MSEC*250)) * (USEC_PER_MSEC*250) + (e->perturb % (USEC_PER_MSEC*250));
1358 if (c >= b) {
1359 if (_unlikely_(c < USEC_PER_MSEC*250))
1360 return b;
1361
1362 c -= USEC_PER_MSEC*250;
1363 }
1364
1365 if (c >= a)
1366 return c;
1367
1368 return b;
1369}
1370
fd38203a
LP
1371static int event_arm_timer(
1372 sd_event *e,
1373 int timer_fd,
c2ba3ad6
LP
1374 Prioq *earliest,
1375 Prioq *latest,
fd38203a
LP
1376 usec_t *next) {
1377
1378 struct itimerspec its = {};
c2ba3ad6
LP
1379 sd_event_source *a, *b;
1380 usec_t t;
fd38203a
LP
1381 int r;
1382
1383 assert_se(e);
1384 assert_se(next);
1385
c2ba3ad6 1386 a = prioq_peek(earliest);
baf76283 1387 if (!a || a->enabled == SD_EVENT_OFF)
fd38203a
LP
1388 return 0;
1389
c2ba3ad6 1390 b = prioq_peek(latest);
baf76283 1391 assert_se(b && b->enabled != SD_EVENT_OFF);
c2ba3ad6
LP
1392
1393 t = sleep_between(e, a->time.next, b->time.next + b->time.accuracy);
1394 if (*next == t)
fd38203a
LP
1395 return 0;
1396
1397 assert_se(timer_fd >= 0);
1398
c2ba3ad6 1399 if (t == 0) {
fd38203a
LP
1400 /* We don' want to disarm here, just mean some time looooong ago. */
1401 its.it_value.tv_sec = 0;
1402 its.it_value.tv_nsec = 1;
1403 } else
c2ba3ad6 1404 timespec_store(&its.it_value, t);
fd38203a
LP
1405
1406 r = timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &its, NULL);
1407 if (r < 0)
1408 return r;
1409
c2ba3ad6 1410 *next = t;
fd38203a
LP
1411 return 0;
1412}
1413
1414static int process_io(sd_event *e, sd_event_source *s, uint32_t events) {
1415 assert(e);
1416 assert(s);
1417 assert(s->type == SOURCE_IO);
1418
1419 s->io.revents = events;
1420
1421 /*
1422 If this is a oneshot event source, then we added it to the
1423 epoll with EPOLLONESHOT, hence we know it's not registered
1424 anymore. We can save a syscall here...
1425 */
1426
baf76283 1427 if (s->enabled == SD_EVENT_ONESHOT)
fd38203a
LP
1428 s->io.registered = false;
1429
1430 return source_set_pending(s, true);
1431}
1432
1433static int flush_timer(sd_event *e, int fd, uint32_t events) {
1434 uint64_t x;
1435 ssize_t ss;
1436
1437 assert(e);
da7e457c 1438 assert(fd >= 0);
305f78bf 1439 assert_return(events == EPOLLIN, -EIO);
fd38203a
LP
1440
1441 ss = read(fd, &x, sizeof(x));
1442 if (ss < 0) {
1443 if (errno == EAGAIN || errno == EINTR)
1444 return 0;
1445
1446 return -errno;
1447 }
1448
1449 if (ss != sizeof(x))
1450 return -EIO;
1451
1452 return 0;
1453}
1454
305f78bf
LP
1455static int process_timer(
1456 sd_event *e,
1457 usec_t n,
1458 Prioq *earliest,
1459 Prioq *latest) {
1460
fd38203a
LP
1461 sd_event_source *s;
1462 int r;
1463
1464 assert(e);
1465
1466 for (;;) {
c2ba3ad6 1467 s = prioq_peek(earliest);
fd38203a
LP
1468 if (!s ||
1469 s->time.next > n ||
baf76283 1470 s->enabled == SD_EVENT_OFF ||
fd38203a
LP
1471 s->pending)
1472 break;
1473
1474 r = source_set_pending(s, true);
1475 if (r < 0)
1476 return r;
1477
c2ba3ad6
LP
1478 prioq_reshuffle(earliest, s, &s->time.earliest_index);
1479 prioq_reshuffle(latest, s, &s->time.latest_index);
fd38203a
LP
1480 }
1481
1482 return 0;
1483}
1484
1485static int process_child(sd_event *e) {
1486 sd_event_source *s;
1487 Iterator i;
1488 int r;
1489
1490 assert(e);
1491
c2ba3ad6
LP
1492 e->need_process_child = false;
1493
fd38203a
LP
1494 /*
1495 So, this is ugly. We iteratively invoke waitid() with P_PID
1496 + WNOHANG for each PID we wait for, instead of using
1497 P_ALL. This is because we only want to get child
1498 information of very specific child processes, and not all
1499 of them. We might not have processed the SIGCHLD even of a
1500 previous invocation and we don't want to maintain a
1501 unbounded *per-child* event queue, hence we really don't
1502 want anything flushed out of the kernel's queue that we
1503 don't care about. Since this is O(n) this means that if you
1504 have a lot of processes you probably want to handle SIGCHLD
1505 yourself.
1506 */
1507
1508 HASHMAP_FOREACH(s, e->child_sources, i) {
1509 assert(s->type == SOURCE_CHILD);
1510
1511 if (s->pending)
1512 continue;
1513
baf76283 1514 if (s->enabled == SD_EVENT_OFF)
fd38203a
LP
1515 continue;
1516
1517 zero(s->child.siginfo);
1518 r = waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|s->child.options);
1519 if (r < 0)
1520 return -errno;
1521
1522 if (s->child.siginfo.si_pid != 0) {
1523 r = source_set_pending(s, true);
1524 if (r < 0)
1525 return r;
1526 }
1527 }
1528
fd38203a
LP
1529 return 0;
1530}
1531
1532static int process_signal(sd_event *e, uint32_t events) {
fd38203a 1533 bool read_one = false;
fd38203a
LP
1534 int r;
1535
da7e457c 1536 assert(e);
0eb2e0e3
ZJS
1537 assert(e->signal_sources);
1538
305f78bf 1539 assert_return(events == EPOLLIN, -EIO);
fd38203a
LP
1540
1541 for (;;) {
0eb2e0e3
ZJS
1542 struct signalfd_siginfo si;
1543 ssize_t ss;
fd38203a
LP
1544 sd_event_source *s;
1545
1546 ss = read(e->signal_fd, &si, sizeof(si));
1547 if (ss < 0) {
1548 if (errno == EAGAIN || errno == EINTR)
1549 return read_one;
1550
1551 return -errno;
1552 }
1553
1554 if (ss != sizeof(si))
1555 return -EIO;
1556
1557 read_one = true;
1558
0eb2e0e3 1559 s = e->signal_sources[si.ssi_signo];
fd38203a
LP
1560 if (si.ssi_signo == SIGCHLD) {
1561 r = process_child(e);
1562 if (r < 0)
1563 return r;
0eb2e0e3 1564 if (r > 0 || !s)
fd38203a 1565 continue;
0eb2e0e3 1566 } else
fd38203a
LP
1567 if (!s)
1568 return -EIO;
fd38203a
LP
1569
1570 s->signal.siginfo = si;
1571 r = source_set_pending(s, true);
1572 if (r < 0)
1573 return r;
1574 }
1575
1576
1577 return 0;
1578}
1579
1580static int source_dispatch(sd_event_source *s) {
1581 int r;
1582
1583 assert(s);
da7e457c 1584 assert(s->pending || s->type == SOURCE_QUIT);
fd38203a 1585
da7e457c
LP
1586 if (s->type != SOURCE_DEFER && s->type != SOURCE_QUIT) {
1587 r = source_set_pending(s, false);
1588 if (r < 0)
1589 return r;
1590 }
fd38203a 1591
baf76283
LP
1592 if (s->enabled == SD_EVENT_ONESHOT) {
1593 r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
fd38203a
LP
1594 if (r < 0)
1595 return r;
1596 }
1597
1598 switch (s->type) {
1599
1600 case SOURCE_IO:
1601 r = s->io.callback(s, s->io.fd, s->io.revents, s->userdata);
1602 break;
1603
1604 case SOURCE_MONOTONIC:
1605 r = s->time.callback(s, s->time.next, s->userdata);
1606 break;
1607
1608 case SOURCE_REALTIME:
1609 r = s->time.callback(s, s->time.next, s->userdata);
1610 break;
1611
1612 case SOURCE_SIGNAL:
1613 r = s->signal.callback(s, &s->signal.siginfo, s->userdata);
1614 break;
1615
1616 case SOURCE_CHILD:
1617 r = s->child.callback(s, &s->child.siginfo, s->userdata);
1618 break;
1619
1620 case SOURCE_DEFER:
1621 r = s->defer.callback(s, s->userdata);
1622 break;
da7e457c
LP
1623
1624 case SOURCE_QUIT:
1625 r = s->quit.callback(s, s->userdata);
1626 break;
fd38203a
LP
1627 }
1628
1629 return r;
1630}
1631
1632static int event_prepare(sd_event *e) {
1633 int r;
1634
1635 assert(e);
1636
1637 for (;;) {
1638 sd_event_source *s;
1639
1640 s = prioq_peek(e->prepare);
baf76283 1641 if (!s || s->prepare_iteration == e->iteration || s->enabled == SD_EVENT_OFF)
fd38203a
LP
1642 break;
1643
1644 s->prepare_iteration = e->iteration;
1645 r = prioq_reshuffle(e->prepare, s, &s->prepare_index);
1646 if (r < 0)
1647 return r;
1648
1649 assert(s->prepare);
1650 r = s->prepare(s, s->userdata);
1651 if (r < 0)
1652 return r;
1653
1654 }
1655
1656 return 0;
1657}
1658
da7e457c
LP
1659static int dispatch_quit(sd_event *e) {
1660 sd_event_source *p;
1661 int r;
1662
1663 assert(e);
1664
1665 p = prioq_peek(e->quit);
baf76283 1666 if (!p || p->enabled == SD_EVENT_OFF) {
da7e457c
LP
1667 e->state = SD_EVENT_FINISHED;
1668 return 0;
1669 }
1670
1671 sd_event_ref(e);
1672 e->iteration++;
1673 e->state = SD_EVENT_QUITTING;
1674
1675 r = source_dispatch(p);
1676
1677 e->state = SD_EVENT_PASSIVE;
1678 sd_event_unref(e);
1679
1680 return r;
1681}
1682
c2ba3ad6
LP
1683static sd_event_source* event_next_pending(sd_event *e) {
1684 sd_event_source *p;
1685
da7e457c
LP
1686 assert(e);
1687
c2ba3ad6
LP
1688 p = prioq_peek(e->pending);
1689 if (!p)
1690 return NULL;
1691
baf76283 1692 if (p->enabled == SD_EVENT_OFF)
c2ba3ad6
LP
1693 return NULL;
1694
1695 return p;
1696}
1697
fd38203a
LP
1698int sd_event_run(sd_event *e, uint64_t timeout) {
1699 struct epoll_event ev_queue[EPOLL_QUEUE_MAX];
1700 sd_event_source *p;
305f78bf 1701 int r, i, m;
fd38203a 1702
da7e457c
LP
1703 assert_return(e, -EINVAL);
1704 assert_return(!event_pid_changed(e), -ECHILD);
1705 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
1706 assert_return(e->state == SD_EVENT_PASSIVE, -EBUSY);
1707
1708 if (e->quit_requested)
1709 return dispatch_quit(e);
fd38203a 1710
da7e457c 1711 sd_event_ref(e);
fd38203a 1712 e->iteration++;
da7e457c 1713 e->state = SD_EVENT_RUNNING;
fd38203a
LP
1714
1715 r = event_prepare(e);
1716 if (r < 0)
da7e457c 1717 goto finish;
fd38203a 1718
c2ba3ad6
LP
1719 if (event_next_pending(e) || e->need_process_child)
1720 timeout = 0;
fd38203a 1721
c2ba3ad6
LP
1722 if (timeout > 0) {
1723 r = event_arm_timer(e, e->monotonic_fd, e->monotonic_earliest, e->monotonic_latest, &e->monotonic_next);
1724 if (r < 0)
da7e457c 1725 goto finish;
fd38203a 1726
c2ba3ad6
LP
1727 r = event_arm_timer(e, e->realtime_fd, e->realtime_earliest, e->realtime_latest, &e->realtime_next);
1728 if (r < 0)
da7e457c 1729 goto finish;
fd38203a
LP
1730 }
1731
c2ba3ad6
LP
1732 m = epoll_wait(e->epoll_fd, ev_queue, EPOLL_QUEUE_MAX,
1733 timeout == (uint64_t) -1 ? -1 : (int) ((timeout + USEC_PER_MSEC - 1) / USEC_PER_MSEC));
da7e457c
LP
1734 if (m < 0) {
1735 r = m;
1736 goto finish;
1737 }
fd38203a 1738
46e8c825 1739 dual_timestamp_get(&e->timestamp);
fd38203a
LP
1740
1741 for (i = 0; i < m; i++) {
1742
1743 if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_MONOTONIC))
1744 r = flush_timer(e, e->monotonic_fd, ev_queue[i].events);
1745 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_REALTIME))
1746 r = flush_timer(e, e->realtime_fd, ev_queue[i].events);
1747 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_SIGNAL))
1748 r = process_signal(e, ev_queue[i].events);
1749 else
1750 r = process_io(e, ev_queue[i].data.ptr, ev_queue[i].events);
1751
1752 if (r < 0)
da7e457c 1753 goto finish;
fd38203a
LP
1754 }
1755
46e8c825 1756 r = process_timer(e, e->timestamp.monotonic, e->monotonic_earliest, e->monotonic_latest);
fd38203a 1757 if (r < 0)
da7e457c 1758 goto finish;
fd38203a 1759
46e8c825 1760 r = process_timer(e, e->timestamp.realtime, e->realtime_earliest, e->realtime_latest);
fd38203a 1761 if (r < 0)
da7e457c 1762 goto finish;
fd38203a 1763
c2ba3ad6 1764 if (e->need_process_child) {
fd38203a
LP
1765 r = process_child(e);
1766 if (r < 0)
da7e457c 1767 goto finish;
fd38203a
LP
1768 }
1769
c2ba3ad6 1770 p = event_next_pending(e);
da7e457c
LP
1771 if (!p) {
1772 r = 0;
1773 goto finish;
1774 }
1775
1776 r = source_dispatch(p);
fd38203a 1777
da7e457c
LP
1778finish:
1779 e->state = SD_EVENT_PASSIVE;
1780 sd_event_unref(e);
1781
1782 return r;
fd38203a
LP
1783}
1784
1785int sd_event_loop(sd_event *e) {
1786 int r;
1787
da7e457c
LP
1788 assert_return(e, -EINVAL);
1789 assert_return(!event_pid_changed(e), -ECHILD);
1790 assert_return(e->state == SD_EVENT_PASSIVE, -EBUSY);
1791
1792 sd_event_ref(e);
fd38203a 1793
da7e457c 1794 while (e->state != SD_EVENT_FINISHED) {
fd38203a
LP
1795 r = sd_event_run(e, (uint64_t) -1);
1796 if (r < 0)
da7e457c 1797 goto finish;
fd38203a
LP
1798 }
1799
da7e457c
LP
1800 r = 0;
1801
1802finish:
1803 sd_event_unref(e);
1804 return r;
fd38203a
LP
1805}
1806
da7e457c
LP
1807int sd_event_get_state(sd_event *e) {
1808 assert_return(e, -EINVAL);
1809 assert_return(!event_pid_changed(e), -ECHILD);
1810
1811 return e->state;
1812}
1813
1814int sd_event_get_quit(sd_event *e) {
1815 assert_return(e, -EINVAL);
1816 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 1817
da7e457c 1818 return e->quit_requested;
fd38203a
LP
1819}
1820
1821int sd_event_request_quit(sd_event *e) {
da7e457c
LP
1822 assert_return(e, -EINVAL);
1823 assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
1824 assert_return(!event_pid_changed(e), -ECHILD);
fd38203a 1825
da7e457c 1826 e->quit_requested = true;
fd38203a
LP
1827 return 0;
1828}
46e8c825
LP
1829
1830int sd_event_get_now_realtime(sd_event *e, uint64_t *usec) {
1831 assert_return(e, -EINVAL);
1832 assert_return(usec, -EINVAL);
1833 assert_return(dual_timestamp_is_set(&e->timestamp), -ENODATA);
1834 assert_return(!event_pid_changed(e), -ECHILD);
1835
1836 *usec = e->timestamp.realtime;
1837 return 0;
1838}
1839
1840int sd_event_get_now_monotonic(sd_event *e, uint64_t *usec) {
1841 assert_return(e, -EINVAL);
1842 assert_return(usec, -EINVAL);
1843 assert_return(dual_timestamp_is_set(&e->timestamp), -ENODATA);
1844 assert_return(!event_pid_changed(e), -ECHILD);
1845
1846 *usec = e->timestamp.monotonic;
1847 return 0;
1848}