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