LCOV - code coverage report
Current view: top level - libsystemd/sd-event - sd-event.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 920 1376 66.9 %
Date: 2015-07-29 18:47:03 Functions: 57 85 67.1 %

          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             : }

Generated by: LCOV version 1.11