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