LCOV - code coverage report
Current view: top level - libsystemd/sd-event - sd-event.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 1394 1885 74.0 %
Date: 2019-08-23 13:36:53 Functions: 89 117 76.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1058 2094 50.5 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <sys/epoll.h>
       4                 :            : #include <sys/timerfd.h>
       5                 :            : #include <sys/wait.h>
       6                 :            : 
       7                 :            : #include "sd-daemon.h"
       8                 :            : #include "sd-event.h"
       9                 :            : #include "sd-id128.h"
      10                 :            : 
      11                 :            : #include "alloc-util.h"
      12                 :            : #include "event-source.h"
      13                 :            : #include "fd-util.h"
      14                 :            : #include "fs-util.h"
      15                 :            : #include "hashmap.h"
      16                 :            : #include "list.h"
      17                 :            : #include "macro.h"
      18                 :            : #include "memory-util.h"
      19                 :            : #include "missing.h"
      20                 :            : #include "prioq.h"
      21                 :            : #include "process-util.h"
      22                 :            : #include "set.h"
      23                 :            : #include "signal-util.h"
      24                 :            : #include "string-table.h"
      25                 :            : #include "string-util.h"
      26                 :            : #include "strxcpyx.h"
      27                 :            : #include "time-util.h"
      28                 :            : 
      29                 :            : #define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC)
      30                 :            : 
      31                 :            : static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] = {
      32                 :            :         [SOURCE_IO] = "io",
      33                 :            :         [SOURCE_TIME_REALTIME] = "realtime",
      34                 :            :         [SOURCE_TIME_BOOTTIME] = "bootime",
      35                 :            :         [SOURCE_TIME_MONOTONIC] = "monotonic",
      36                 :            :         [SOURCE_TIME_REALTIME_ALARM] = "realtime-alarm",
      37                 :            :         [SOURCE_TIME_BOOTTIME_ALARM] = "boottime-alarm",
      38                 :            :         [SOURCE_SIGNAL] = "signal",
      39                 :            :         [SOURCE_CHILD] = "child",
      40                 :            :         [SOURCE_DEFER] = "defer",
      41                 :            :         [SOURCE_POST] = "post",
      42                 :            :         [SOURCE_EXIT] = "exit",
      43                 :            :         [SOURCE_WATCHDOG] = "watchdog",
      44                 :            :         [SOURCE_INOTIFY] = "inotify",
      45                 :            : };
      46                 :            : 
      47   [ #  #  #  # ]:          0 : DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(event_source_type, int);
      48                 :            : 
      49                 :            : #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)
      50                 :            : 
      51                 :            : struct sd_event {
      52                 :            :         unsigned n_ref;
      53                 :            : 
      54                 :            :         int epoll_fd;
      55                 :            :         int watchdog_fd;
      56                 :            : 
      57                 :            :         Prioq *pending;
      58                 :            :         Prioq *prepare;
      59                 :            : 
      60                 :            :         /* timerfd_create() only supports these five clocks so far. We
      61                 :            :          * can add support for more clocks when the kernel learns to
      62                 :            :          * deal with them, too. */
      63                 :            :         struct clock_data realtime;
      64                 :            :         struct clock_data boottime;
      65                 :            :         struct clock_data monotonic;
      66                 :            :         struct clock_data realtime_alarm;
      67                 :            :         struct clock_data boottime_alarm;
      68                 :            : 
      69                 :            :         usec_t perturb;
      70                 :            : 
      71                 :            :         sd_event_source **signal_sources; /* indexed by signal number */
      72                 :            :         Hashmap *signal_data; /* indexed by priority */
      73                 :            : 
      74                 :            :         Hashmap *child_sources;
      75                 :            :         unsigned n_enabled_child_sources;
      76                 :            : 
      77                 :            :         Set *post_sources;
      78                 :            : 
      79                 :            :         Prioq *exit;
      80                 :            : 
      81                 :            :         Hashmap *inotify_data; /* indexed by priority */
      82                 :            : 
      83                 :            :         /* A list of inode structures that still have an fd open, that we need to close before the next loop iteration */
      84                 :            :         LIST_HEAD(struct inode_data, inode_data_to_close);
      85                 :            : 
      86                 :            :         /* A list of inotify objects that already have events buffered which aren't processed yet */
      87                 :            :         LIST_HEAD(struct inotify_data, inotify_data_buffered);
      88                 :            : 
      89                 :            :         pid_t original_pid;
      90                 :            : 
      91                 :            :         uint64_t iteration;
      92                 :            :         triple_timestamp timestamp;
      93                 :            :         int state;
      94                 :            : 
      95                 :            :         bool exit_requested:1;
      96                 :            :         bool need_process_child:1;
      97                 :            :         bool watchdog:1;
      98                 :            :         bool profile_delays:1;
      99                 :            : 
     100                 :            :         int exit_code;
     101                 :            : 
     102                 :            :         pid_t tid;
     103                 :            :         sd_event **default_event_ptr;
     104                 :            : 
     105                 :            :         usec_t watchdog_last, watchdog_period;
     106                 :            : 
     107                 :            :         unsigned n_sources;
     108                 :            : 
     109                 :            :         LIST_HEAD(sd_event_source, sources);
     110                 :            : 
     111                 :            :         usec_t last_run, last_log;
     112                 :            :         unsigned delays[sizeof(usec_t) * 8];
     113                 :            : };
     114                 :            : 
     115                 :            : static thread_local sd_event *default_event = NULL;
     116                 :            : 
     117                 :            : static void source_disconnect(sd_event_source *s);
     118                 :            : static void event_gc_inode_data(sd_event *e, struct inode_data *d);
     119                 :            : 
     120                 :     837264 : static sd_event *event_resolve(sd_event *e) {
     121         [ -  + ]:     837264 :         return e == SD_EVENT_DEFAULT ? default_event : e;
     122                 :            : }
     123                 :            : 
     124                 :     373567 : static int pending_prioq_compare(const void *a, const void *b) {
     125                 :     373567 :         const sd_event_source *x = a, *y = b;
     126                 :            :         int r;
     127                 :            : 
     128         [ -  + ]:     373567 :         assert(x->pending);
     129         [ -  + ]:     373567 :         assert(y->pending);
     130                 :            : 
     131                 :            :         /* Enabled ones first */
     132   [ +  +  +  + ]:     373567 :         if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
     133                 :      33483 :                 return -1;
     134   [ +  +  +  + ]:     340084 :         if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
     135                 :      16537 :                 return 1;
     136                 :            : 
     137                 :            :         /* Lower priority values first */
     138         [ +  + ]:     323547 :         r = CMP(x->priority, y->priority);
     139         [ +  + ]:     323547 :         if (r != 0)
     140                 :     221318 :                 return r;
     141                 :            : 
     142                 :            :         /* Older entries first */
     143         [ +  + ]:     102229 :         return CMP(x->pending_iteration, y->pending_iteration);
     144                 :            : }
     145                 :            : 
     146                 :   20741612 : static int prepare_prioq_compare(const void *a, const void *b) {
     147                 :   20741612 :         const sd_event_source *x = a, *y = b;
     148                 :            :         int r;
     149                 :            : 
     150         [ -  + ]:   20741612 :         assert(x->prepare);
     151         [ -  + ]:   20741612 :         assert(y->prepare);
     152                 :            : 
     153                 :            :         /* Enabled ones first */
     154   [ +  +  +  + ]:   20741612 :         if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
     155                 :       5145 :                 return -1;
     156   [ +  +  +  + ]:   20736467 :         if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
     157                 :          4 :                 return 1;
     158                 :            : 
     159                 :            :         /* Move most recently prepared ones last, so that we can stop
     160                 :            :          * preparing as soon as we hit one that has already been
     161                 :            :          * prepared in the current iteration */
     162         [ +  + ]:   20736463 :         r = CMP(x->prepare_iteration, y->prepare_iteration);
     163         [ +  + ]:   20736463 :         if (r != 0)
     164                 :    9764612 :                 return r;
     165                 :            : 
     166                 :            :         /* Lower priority values first */
     167         [ +  + ]:   10971851 :         return CMP(x->priority, y->priority);
     168                 :            : }
     169                 :            : 
     170                 :      27284 : static int earliest_time_prioq_compare(const void *a, const void *b) {
     171                 :      27284 :         const sd_event_source *x = a, *y = b;
     172                 :            : 
     173   [ +  -  -  + ]:      27284 :         assert(EVENT_SOURCE_IS_TIME(x->type));
     174         [ -  + ]:      27284 :         assert(x->type == y->type);
     175                 :            : 
     176                 :            :         /* Enabled ones first */
     177   [ +  +  +  + ]:      27284 :         if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
     178                 :       6880 :                 return -1;
     179   [ +  +  +  + ]:      20404 :         if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
     180                 :       3155 :                 return 1;
     181                 :            : 
     182                 :            :         /* Move the pending ones to the end */
     183   [ +  -  +  + ]:      17249 :         if (!x->pending && y->pending)
     184                 :        324 :                 return -1;
     185   [ -  +  #  # ]:      16925 :         if (x->pending && !y->pending)
     186                 :          0 :                 return 1;
     187                 :            : 
     188                 :            :         /* Order by time */
     189         [ +  + ]:      16925 :         return CMP(x->time.next, y->time.next);
     190                 :            : }
     191                 :            : 
     192                 :      34236 : static usec_t time_event_source_latest(const sd_event_source *s) {
     193                 :      34236 :         return usec_add(s->time.next, s->time.accuracy);
     194                 :            : }
     195                 :            : 
     196                 :      27416 : static int latest_time_prioq_compare(const void *a, const void *b) {
     197                 :      27416 :         const sd_event_source *x = a, *y = b;
     198                 :            : 
     199   [ +  -  -  + ]:      27416 :         assert(EVENT_SOURCE_IS_TIME(x->type));
     200         [ -  + ]:      27416 :         assert(x->type == y->type);
     201                 :            : 
     202                 :            :         /* Enabled ones first */
     203   [ +  +  +  + ]:      27416 :         if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
     204                 :       7008 :                 return -1;
     205   [ +  +  +  + ]:      20408 :         if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
     206                 :       3155 :                 return 1;
     207                 :            : 
     208                 :            :         /* Move the pending ones to the end */
     209   [ +  -  +  + ]:      17253 :         if (!x->pending && y->pending)
     210                 :        324 :                 return -1;
     211   [ -  +  #  # ]:      16929 :         if (x->pending && !y->pending)
     212                 :          0 :                 return 1;
     213                 :            : 
     214                 :            :         /* Order by time */
     215         [ +  + ]:      16929 :         return CMP(time_event_source_latest(x), time_event_source_latest(y));
     216                 :            : }
     217                 :            : 
     218                 :      35862 : static int exit_prioq_compare(const void *a, const void *b) {
     219                 :      35862 :         const sd_event_source *x = a, *y = b;
     220                 :            : 
     221         [ -  + ]:      35862 :         assert(x->type == SOURCE_EXIT);
     222         [ -  + ]:      35862 :         assert(y->type == SOURCE_EXIT);
     223                 :            : 
     224                 :            :         /* Enabled ones first */
     225   [ +  -  +  + ]:      35862 :         if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
     226                 :       5864 :                 return -1;
     227   [ -  +  #  # ]:      29998 :         if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
     228                 :          0 :                 return 1;
     229                 :            : 
     230                 :            :         /* Lower priority values first */
     231         [ +  + ]:      29998 :         return CMP(x->priority, y->priority);
     232                 :            : }
     233                 :            : 
     234                 :        740 : static void free_clock_data(struct clock_data *d) {
     235         [ -  + ]:        740 :         assert(d);
     236         [ -  + ]:        740 :         assert(d->wakeup == WAKEUP_CLOCK_DATA);
     237                 :            : 
     238                 :        740 :         safe_close(d->fd);
     239                 :        740 :         prioq_free(d->earliest);
     240                 :        740 :         prioq_free(d->latest);
     241                 :        740 : }
     242                 :            : 
     243                 :        148 : static sd_event *event_free(sd_event *e) {
     244                 :            :         sd_event_source *s;
     245                 :            : 
     246         [ -  + ]:        148 :         assert(e);
     247                 :            : 
     248         [ +  + ]:        160 :         while ((s = e->sources)) {
     249         [ -  + ]:         12 :                 assert(s->floating);
     250                 :         12 :                 source_disconnect(s);
     251                 :         12 :                 sd_event_source_unref(s);
     252                 :            :         }
     253                 :            : 
     254         [ -  + ]:        148 :         assert(e->n_sources == 0);
     255                 :            : 
     256         [ +  + ]:        148 :         if (e->default_event_ptr)
     257                 :        100 :                 *(e->default_event_ptr) = NULL;
     258                 :            : 
     259                 :        148 :         safe_close(e->epoll_fd);
     260                 :        148 :         safe_close(e->watchdog_fd);
     261                 :            : 
     262                 :        148 :         free_clock_data(&e->realtime);
     263                 :        148 :         free_clock_data(&e->boottime);
     264                 :        148 :         free_clock_data(&e->monotonic);
     265                 :        148 :         free_clock_data(&e->realtime_alarm);
     266                 :        148 :         free_clock_data(&e->boottime_alarm);
     267                 :            : 
     268                 :        148 :         prioq_free(e->pending);
     269                 :        148 :         prioq_free(e->prepare);
     270                 :        148 :         prioq_free(e->exit);
     271                 :            : 
     272                 :        148 :         free(e->signal_sources);
     273                 :        148 :         hashmap_free(e->signal_data);
     274                 :            : 
     275                 :        148 :         hashmap_free(e->inotify_data);
     276                 :            : 
     277                 :        148 :         hashmap_free(e->child_sources);
     278                 :        148 :         set_free(e->post_sources);
     279                 :            : 
     280                 :        148 :         return mfree(e);
     281                 :            : }
     282                 :            : 
     283                 :        152 : _public_ int sd_event_new(sd_event** ret) {
     284                 :            :         sd_event *e;
     285                 :            :         int r;
     286                 :            : 
     287   [ -  +  -  + ]:        152 :         assert_return(ret, -EINVAL);
     288                 :            : 
     289                 :        152 :         e = new(sd_event, 1);
     290         [ -  + ]:        152 :         if (!e)
     291                 :          0 :                 return -ENOMEM;
     292                 :            : 
     293                 :        152 :         *e = (sd_event) {
     294                 :            :                 .n_ref = 1,
     295                 :            :                 .epoll_fd = -1,
     296                 :            :                 .watchdog_fd = -1,
     297                 :            :                 .realtime.wakeup = WAKEUP_CLOCK_DATA,
     298                 :            :                 .realtime.fd = -1,
     299                 :            :                 .realtime.next = USEC_INFINITY,
     300                 :            :                 .boottime.wakeup = WAKEUP_CLOCK_DATA,
     301                 :            :                 .boottime.fd = -1,
     302                 :            :                 .boottime.next = USEC_INFINITY,
     303                 :            :                 .monotonic.wakeup = WAKEUP_CLOCK_DATA,
     304                 :            :                 .monotonic.fd = -1,
     305                 :            :                 .monotonic.next = USEC_INFINITY,
     306                 :            :                 .realtime_alarm.wakeup = WAKEUP_CLOCK_DATA,
     307                 :            :                 .realtime_alarm.fd = -1,
     308                 :            :                 .realtime_alarm.next = USEC_INFINITY,
     309                 :            :                 .boottime_alarm.wakeup = WAKEUP_CLOCK_DATA,
     310                 :            :                 .boottime_alarm.fd = -1,
     311                 :            :                 .boottime_alarm.next = USEC_INFINITY,
     312                 :            :                 .perturb = USEC_INFINITY,
     313                 :        152 :                 .original_pid = getpid_cached(),
     314                 :            :         };
     315                 :            : 
     316                 :        152 :         r = prioq_ensure_allocated(&e->pending, pending_prioq_compare);
     317         [ -  + ]:        152 :         if (r < 0)
     318                 :          0 :                 goto fail;
     319                 :            : 
     320                 :        152 :         e->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
     321         [ -  + ]:        152 :         if (e->epoll_fd < 0) {
     322                 :          0 :                 r = -errno;
     323                 :          0 :                 goto fail;
     324                 :            :         }
     325                 :            : 
     326                 :        152 :         e->epoll_fd = fd_move_above_stdio(e->epoll_fd);
     327                 :            : 
     328         [ -  + ]:        152 :         if (secure_getenv("SD_EVENT_PROFILE_DELAYS")) {
     329         [ #  # ]:          0 :                 log_debug("Event loop profiling enabled. Logarithmic histogram of event loop iterations in the range 2^0 ... 2^63 us will be logged every 5s.");
     330                 :          0 :                 e->profile_delays = true;
     331                 :            :         }
     332                 :            : 
     333                 :        152 :         *ret = e;
     334                 :        152 :         return 0;
     335                 :            : 
     336                 :          0 : fail:
     337                 :          0 :         event_free(e);
     338                 :          0 :         return r;
     339                 :            : }
     340                 :            : 
     341   [ +  +  -  +  :     437538 : DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_event, sd_event, event_free);
                   +  + ]
     342                 :            : 
     343                 :      14948 : _public_ sd_event_source* sd_event_source_disable_unref(sd_event_source *s) {
     344         [ +  + ]:      14948 :         if (s)
     345                 :       7460 :                 (void) sd_event_source_set_enabled(s, SD_EVENT_OFF);
     346                 :      14948 :         return sd_event_source_unref(s);
     347                 :            : }
     348                 :            : 
     349                 :    3952717 : static bool event_pid_changed(sd_event *e) {
     350         [ -  + ]:    3952717 :         assert(e);
     351                 :            : 
     352                 :            :         /* We don't support people creating an event loop and keeping
     353                 :            :          * it around over a fork(). Let's complain. */
     354                 :            : 
     355                 :    3952717 :         return e->original_pid != getpid_cached();
     356                 :            : }
     357                 :            : 
     358                 :       4432 : static void source_io_unregister(sd_event_source *s) {
     359                 :            :         int r;
     360                 :            : 
     361         [ -  + ]:       4432 :         assert(s);
     362         [ -  + ]:       4432 :         assert(s->type == SOURCE_IO);
     363                 :            : 
     364         [ -  + ]:       4432 :         if (event_pid_changed(s->event))
     365                 :          0 :                 return;
     366                 :            : 
     367         [ +  + ]:       4432 :         if (!s->io.registered)
     368                 :       2004 :                 return;
     369                 :            : 
     370                 :       2428 :         r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, s->io.fd, NULL);
     371         [ -  + ]:       2428 :         if (r < 0)
     372         [ #  # ]:          0 :                 log_debug_errno(errno, "Failed to remove source %s (type %s) from epoll: %m",
     373                 :            :                                 strna(s->description), event_source_type_to_string(s->type));
     374                 :            : 
     375                 :       2428 :         s->io.registered = false;
     376                 :            : }
     377                 :            : 
     378                 :       7125 : static int source_io_register(
     379                 :            :                 sd_event_source *s,
     380                 :            :                 int enabled,
     381                 :            :                 uint32_t events) {
     382                 :            : 
     383                 :            :         struct epoll_event ev;
     384                 :            :         int r;
     385                 :            : 
     386         [ -  + ]:       7125 :         assert(s);
     387         [ -  + ]:       7125 :         assert(s->type == SOURCE_IO);
     388         [ -  + ]:       7125 :         assert(enabled != SD_EVENT_OFF);
     389                 :            : 
     390                 :       7125 :         ev = (struct epoll_event) {
     391         [ +  + ]:       7125 :                 .events = events | (enabled == SD_EVENT_ONESHOT ? EPOLLONESHOT : 0),
     392                 :            :                 .data.ptr = s,
     393                 :            :         };
     394                 :            : 
     395         [ +  + ]:       7125 :         if (s->io.registered)
     396                 :       4693 :                 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_MOD, s->io.fd, &ev);
     397                 :            :         else
     398                 :       2432 :                 r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_ADD, s->io.fd, &ev);
     399         [ -  + ]:       7125 :         if (r < 0)
     400                 :          0 :                 return -errno;
     401                 :            : 
     402                 :       7125 :         s->io.registered = true;
     403                 :            : 
     404                 :       7125 :         return 0;
     405                 :            : }
     406                 :            : 
     407                 :        172 : static clockid_t event_source_type_to_clock(EventSourceType t) {
     408                 :            : 
     409   [ -  +  -  -  :        172 :         switch (t) {
                   -  - ]
     410                 :            : 
     411                 :          0 :         case SOURCE_TIME_REALTIME:
     412                 :          0 :                 return CLOCK_REALTIME;
     413                 :            : 
     414                 :        172 :         case SOURCE_TIME_BOOTTIME:
     415                 :        172 :                 return CLOCK_BOOTTIME;
     416                 :            : 
     417                 :          0 :         case SOURCE_TIME_MONOTONIC:
     418                 :          0 :                 return CLOCK_MONOTONIC;
     419                 :            : 
     420                 :          0 :         case SOURCE_TIME_REALTIME_ALARM:
     421                 :          0 :                 return CLOCK_REALTIME_ALARM;
     422                 :            : 
     423                 :          0 :         case SOURCE_TIME_BOOTTIME_ALARM:
     424                 :          0 :                 return CLOCK_BOOTTIME_ALARM;
     425                 :            : 
     426                 :          0 :         default:
     427                 :          0 :                 return (clockid_t) -1;
     428                 :            :         }
     429                 :            : }
     430                 :            : 
     431                 :       2056 : static EventSourceType clock_to_event_source_type(clockid_t clock) {
     432                 :            : 
     433   [ -  +  +  -  :       2056 :         switch (clock) {
                   -  - ]
     434                 :            : 
     435                 :          0 :         case CLOCK_REALTIME:
     436                 :          0 :                 return SOURCE_TIME_REALTIME;
     437                 :            : 
     438                 :         76 :         case CLOCK_BOOTTIME:
     439                 :         76 :                 return SOURCE_TIME_BOOTTIME;
     440                 :            : 
     441                 :       1980 :         case CLOCK_MONOTONIC:
     442                 :       1980 :                 return SOURCE_TIME_MONOTONIC;
     443                 :            : 
     444                 :          0 :         case CLOCK_REALTIME_ALARM:
     445                 :          0 :                 return SOURCE_TIME_REALTIME_ALARM;
     446                 :            : 
     447                 :          0 :         case CLOCK_BOOTTIME_ALARM:
     448                 :          0 :                 return SOURCE_TIME_BOOTTIME_ALARM;
     449                 :            : 
     450                 :          0 :         default:
     451                 :          0 :                 return _SOURCE_EVENT_SOURCE_TYPE_INVALID;
     452                 :            :         }
     453                 :            : }
     454                 :            : 
     455                 :      11718 : static struct clock_data* event_get_clock_data(sd_event *e, EventSourceType t) {
     456         [ -  + ]:      11718 :         assert(e);
     457                 :            : 
     458   [ -  +  +  -  :      11718 :         switch (t) {
                   -  - ]
     459                 :            : 
     460                 :          0 :         case SOURCE_TIME_REALTIME:
     461                 :          0 :                 return &e->realtime;
     462                 :            : 
     463                 :       1120 :         case SOURCE_TIME_BOOTTIME:
     464                 :       1120 :                 return &e->boottime;
     465                 :            : 
     466                 :      10598 :         case SOURCE_TIME_MONOTONIC:
     467                 :      10598 :                 return &e->monotonic;
     468                 :            : 
     469                 :          0 :         case SOURCE_TIME_REALTIME_ALARM:
     470                 :          0 :                 return &e->realtime_alarm;
     471                 :            : 
     472                 :          0 :         case SOURCE_TIME_BOOTTIME_ALARM:
     473                 :          0 :                 return &e->boottime_alarm;
     474                 :            : 
     475                 :          0 :         default:
     476                 :          0 :                 return NULL;
     477                 :            :         }
     478                 :            : }
     479                 :            : 
     480                 :         16 : static void event_free_signal_data(sd_event *e, struct signal_data *d) {
     481         [ -  + ]:         16 :         assert(e);
     482                 :            : 
     483         [ -  + ]:         16 :         if (!d)
     484                 :          0 :                 return;
     485                 :            : 
     486                 :         16 :         hashmap_remove(e->signal_data, &d->priority);
     487                 :         16 :         safe_close(d->fd);
     488                 :         16 :         free(d);
     489                 :            : }
     490                 :            : 
     491                 :         32 : static int event_make_signal_data(
     492                 :            :                 sd_event *e,
     493                 :            :                 int sig,
     494                 :            :                 struct signal_data **ret) {
     495                 :            : 
     496                 :            :         struct epoll_event ev;
     497                 :            :         struct signal_data *d;
     498                 :         32 :         bool added = false;
     499                 :            :         sigset_t ss_copy;
     500                 :            :         int64_t priority;
     501                 :            :         int r;
     502                 :            : 
     503         [ -  + ]:         32 :         assert(e);
     504                 :            : 
     505         [ -  + ]:         32 :         if (event_pid_changed(e))
     506                 :          0 :                 return -ECHILD;
     507                 :            : 
     508   [ +  -  +  + ]:         32 :         if (e->signal_sources && e->signal_sources[sig])
     509                 :         28 :                 priority = e->signal_sources[sig]->priority;
     510                 :            :         else
     511                 :          4 :                 priority = SD_EVENT_PRIORITY_NORMAL;
     512                 :            : 
     513                 :         32 :         d = hashmap_get(e->signal_data, &priority);
     514         [ +  + ]:         32 :         if (d) {
     515         [ +  + ]:         16 :                 if (sigismember(&d->sigset, sig) > 0) {
     516         [ -  + ]:          4 :                         if (ret)
     517                 :          0 :                                 *ret = d;
     518                 :          4 :                         return 0;
     519                 :            :                 }
     520                 :            :         } else {
     521                 :         16 :                 r = hashmap_ensure_allocated(&e->signal_data, &uint64_hash_ops);
     522         [ -  + ]:         16 :                 if (r < 0)
     523                 :          0 :                         return r;
     524                 :            : 
     525                 :         16 :                 d = new(struct signal_data, 1);
     526         [ -  + ]:         16 :                 if (!d)
     527                 :          0 :                         return -ENOMEM;
     528                 :            : 
     529                 :         16 :                 *d = (struct signal_data) {
     530                 :            :                         .wakeup = WAKEUP_SIGNAL_DATA,
     531                 :            :                         .fd = -1,
     532                 :            :                         .priority = priority,
     533                 :            :                 };
     534                 :            : 
     535                 :         16 :                 r = hashmap_put(e->signal_data, &d->priority, d);
     536         [ -  + ]:         16 :                 if (r < 0) {
     537                 :          0 :                         free(d);
     538                 :          0 :                         return r;
     539                 :            :                 }
     540                 :            : 
     541                 :         16 :                 added = true;
     542                 :            :         }
     543                 :            : 
     544                 :         28 :         ss_copy = d->sigset;
     545         [ -  + ]:         28 :         assert_se(sigaddset(&ss_copy, sig) >= 0);
     546                 :            : 
     547                 :         28 :         r = signalfd(d->fd, &ss_copy, SFD_NONBLOCK|SFD_CLOEXEC);
     548         [ -  + ]:         28 :         if (r < 0) {
     549                 :          0 :                 r = -errno;
     550                 :          0 :                 goto fail;
     551                 :            :         }
     552                 :            : 
     553                 :         28 :         d->sigset = ss_copy;
     554                 :            : 
     555         [ +  + ]:         28 :         if (d->fd >= 0) {
     556         [ +  - ]:         12 :                 if (ret)
     557                 :         12 :                         *ret = d;
     558                 :         12 :                 return 0;
     559                 :            :         }
     560                 :            : 
     561                 :         16 :         d->fd = fd_move_above_stdio(r);
     562                 :            : 
     563                 :         16 :         ev = (struct epoll_event) {
     564                 :            :                 .events = EPOLLIN,
     565                 :            :                 .data.ptr = d,
     566                 :            :         };
     567                 :            : 
     568                 :         16 :         r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, d->fd, &ev);
     569         [ -  + ]:         16 :         if (r < 0)  {
     570                 :          0 :                 r = -errno;
     571                 :          0 :                 goto fail;
     572                 :            :         }
     573                 :            : 
     574         [ +  + ]:         16 :         if (ret)
     575                 :         12 :                 *ret = d;
     576                 :            : 
     577                 :         16 :         return 0;
     578                 :            : 
     579                 :          0 : fail:
     580         [ #  # ]:          0 :         if (added)
     581                 :          0 :                 event_free_signal_data(e, d);
     582                 :            : 
     583                 :          0 :         return r;
     584                 :            : }
     585                 :            : 
     586                 :         40 : static void event_unmask_signal_data(sd_event *e, struct signal_data *d, int sig) {
     587         [ -  + ]:         40 :         assert(e);
     588         [ -  + ]:         40 :         assert(d);
     589                 :            : 
     590                 :            :         /* Turns off the specified signal in the signal data
     591                 :            :          * object. If the signal mask of the object becomes empty that
     592                 :            :          * way removes it. */
     593                 :            : 
     594         [ +  + ]:         40 :         if (sigismember(&d->sigset, sig) == 0)
     595                 :         16 :                 return;
     596                 :            : 
     597         [ -  + ]:         24 :         assert_se(sigdelset(&d->sigset, sig) >= 0);
     598                 :            : 
     599         [ +  + ]:         24 :         if (sigisemptyset(&d->sigset)) {
     600                 :            :                 /* If all the mask is all-zero we can get rid of the structure */
     601                 :         16 :                 event_free_signal_data(e, d);
     602                 :         16 :                 return;
     603                 :            :         }
     604                 :            : 
     605         [ -  + ]:          8 :         assert(d->fd >= 0);
     606                 :            : 
     607         [ -  + ]:          8 :         if (signalfd(d->fd, &d->sigset, SFD_NONBLOCK|SFD_CLOEXEC) < 0)
     608         [ #  # ]:          0 :                 log_debug_errno(errno, "Failed to unset signal bit, ignoring: %m");
     609                 :            : }
     610                 :            : 
     611                 :         32 : static void event_gc_signal_data(sd_event *e, const int64_t *priority, int sig) {
     612                 :            :         struct signal_data *d;
     613                 :            :         static const int64_t zero_priority = 0;
     614                 :            : 
     615         [ -  + ]:         32 :         assert(e);
     616                 :            : 
     617                 :            :         /* Rechecks if the specified signal is still something we are
     618                 :            :          * interested in. If not, we'll unmask it, and possibly drop
     619                 :            :          * the signalfd for it. */
     620                 :            : 
     621         [ +  + ]:         32 :         if (sig == SIGCHLD &&
     622         [ -  + ]:          8 :             e->n_enabled_child_sources > 0)
     623                 :          0 :                 return;
     624                 :            : 
     625         [ +  - ]:         32 :         if (e->signal_sources &&
     626         [ +  + ]:         32 :             e->signal_sources[sig] &&
     627         [ -  + ]:          4 :             e->signal_sources[sig]->enabled != SD_EVENT_OFF)
     628                 :          0 :                 return;
     629                 :            : 
     630                 :            :         /*
     631                 :            :          * The specified signal might be enabled in three different queues:
     632                 :            :          *
     633                 :            :          * 1) the one that belongs to the priority passed (if it is non-NULL)
     634                 :            :          * 2) the one that belongs to the priority of the event source of the signal (if there is one)
     635                 :            :          * 3) the 0 priority (to cover the SIGCHLD case)
     636                 :            :          *
     637                 :            :          * Hence, let's remove it from all three here.
     638                 :            :          */
     639                 :            : 
     640         [ +  - ]:         32 :         if (priority) {
     641                 :         32 :                 d = hashmap_get(e->signal_data, priority);
     642         [ +  + ]:         32 :                 if (d)
     643                 :         24 :                         event_unmask_signal_data(e, d, sig);
     644                 :            :         }
     645                 :            : 
     646   [ +  -  +  + ]:         32 :         if (e->signal_sources && e->signal_sources[sig]) {
     647                 :          4 :                 d = hashmap_get(e->signal_data, &e->signal_sources[sig]->priority);
     648         [ -  + ]:          4 :                 if (d)
     649                 :          0 :                         event_unmask_signal_data(e, d, sig);
     650                 :            :         }
     651                 :            : 
     652                 :         32 :         d = hashmap_get(e->signal_data, &zero_priority);
     653         [ +  + ]:         32 :         if (d)
     654                 :         12 :                 event_unmask_signal_data(e, d, sig);
     655                 :            : }
     656                 :            : 
     657                 :      10508 : static void source_disconnect(sd_event_source *s) {
     658                 :            :         sd_event *event;
     659                 :            : 
     660         [ -  + ]:      10508 :         assert(s);
     661                 :            : 
     662         [ +  + ]:      10508 :         if (!s->event)
     663                 :       1956 :                 return;
     664                 :            : 
     665         [ -  + ]:       8552 :         assert(s->event->n_sources > 0);
     666                 :            : 
     667   [ +  +  +  +  :       8552 :         switch (s->type) {
             +  +  +  +  
                      - ]
     668                 :            : 
     669                 :       2424 :         case SOURCE_IO:
     670         [ +  - ]:       2424 :                 if (s->io.fd >= 0)
     671                 :       2424 :                         source_io_unregister(s);
     672                 :            : 
     673                 :       2424 :                 break;
     674                 :            : 
     675                 :       2056 :         case SOURCE_TIME_REALTIME:
     676                 :            :         case SOURCE_TIME_BOOTTIME:
     677                 :            :         case SOURCE_TIME_MONOTONIC:
     678                 :            :         case SOURCE_TIME_REALTIME_ALARM:
     679                 :            :         case SOURCE_TIME_BOOTTIME_ALARM: {
     680                 :            :                 struct clock_data *d;
     681                 :            : 
     682                 :       2056 :                 d = event_get_clock_data(s->event, s->type);
     683         [ -  + ]:       2056 :                 assert(d);
     684                 :            : 
     685                 :       2056 :                 prioq_remove(d->earliest, s, &s->time.earliest_index);
     686                 :       2056 :                 prioq_remove(d->latest, s, &s->time.latest_index);
     687                 :       2056 :                 d->needs_rearm = true;
     688                 :       2056 :                 break;
     689                 :            :         }
     690                 :            : 
     691                 :         20 :         case SOURCE_SIGNAL:
     692         [ +  - ]:         20 :                 if (s->signal.sig > 0) {
     693                 :            : 
     694         [ +  - ]:         20 :                         if (s->event->signal_sources)
     695                 :         20 :                                 s->event->signal_sources[s->signal.sig] = NULL;
     696                 :            : 
     697                 :         20 :                         event_gc_signal_data(s->event, &s->priority, s->signal.sig);
     698                 :            :                 }
     699                 :            : 
     700                 :         20 :                 break;
     701                 :            : 
     702                 :          4 :         case SOURCE_CHILD:
     703         [ +  - ]:          4 :                 if (s->child.pid > 0) {
     704         [ -  + ]:          4 :                         if (s->enabled != SD_EVENT_OFF) {
     705         [ #  # ]:          0 :                                 assert(s->event->n_enabled_child_sources > 0);
     706                 :          0 :                                 s->event->n_enabled_child_sources--;
     707                 :            :                         }
     708                 :            : 
     709                 :          4 :                         (void) hashmap_remove(s->event->child_sources, PID_TO_PTR(s->child.pid));
     710                 :          4 :                         event_gc_signal_data(s->event, &s->priority, SIGCHLD);
     711                 :            :                 }
     712                 :            : 
     713                 :          4 :                 break;
     714                 :            : 
     715                 :       2064 :         case SOURCE_DEFER:
     716                 :            :                 /* nothing */
     717                 :       2064 :                 break;
     718                 :            : 
     719                 :          8 :         case SOURCE_POST:
     720                 :          8 :                 set_remove(s->event->post_sources, s);
     721                 :          8 :                 break;
     722                 :            : 
     723                 :       1944 :         case SOURCE_EXIT:
     724                 :       1944 :                 prioq_remove(s->event->exit, s, &s->exit.prioq_index);
     725                 :       1944 :                 break;
     726                 :            : 
     727                 :         32 :         case SOURCE_INOTIFY: {
     728                 :            :                 struct inode_data *inode_data;
     729                 :            : 
     730                 :         32 :                 inode_data = s->inotify.inode_data;
     731         [ +  - ]:         32 :                 if (inode_data) {
     732                 :            :                         struct inotify_data *inotify_data;
     733         [ -  + ]:         32 :                         assert_se(inotify_data = inode_data->inotify_data);
     734                 :            : 
     735                 :            :                         /* Detach this event source from the inode object */
     736   [ -  +  -  +  :         32 :                         LIST_REMOVE(inotify.by_inode_data, inode_data->event_sources, s);
             +  +  -  + ]
     737                 :         32 :                         s->inotify.inode_data = NULL;
     738                 :            : 
     739         [ -  + ]:         32 :                         if (s->pending) {
     740         [ #  # ]:          0 :                                 assert(inotify_data->n_pending > 0);
     741                 :          0 :                                 inotify_data->n_pending--;
     742                 :            :                         }
     743                 :            : 
     744                 :            :                         /* Note that we don't reduce the inotify mask for the watch descriptor here if the inode is
     745                 :            :                          * continued to being watched. That's because inotify doesn't really have an API for that: we
     746                 :            :                          * can only change watch masks with access to the original inode either by fd or by path. But
     747                 :            :                          * paths aren't stable, and keeping an O_PATH fd open all the time would mean wasting an fd
     748                 :            :                          * continuously and keeping the mount busy which we can't really do. We could reconstruct the
     749                 :            :                          * original inode from /proc/self/fdinfo/$INOTIFY_FD (as all watch descriptors are listed
     750                 :            :                          * there), but given the need for open_by_handle_at() which is privileged and not universally
     751                 :            :                          * available this would be quite an incomplete solution. Hence we go the other way, leave the
     752                 :            :                          * mask set, even if it is not minimized now, and ignore all events we aren't interested in
     753                 :            :                          * anymore after reception. Yes, this sucks, but … Linux … */
     754                 :            : 
     755                 :            :                         /* Maybe release the inode data (and its inotify) */
     756                 :         32 :                         event_gc_inode_data(s->event, inode_data);
     757                 :            :                 }
     758                 :            : 
     759                 :         32 :                 break;
     760                 :            :         }
     761                 :            : 
     762                 :          0 :         default:
     763                 :          0 :                 assert_not_reached("Wut? I shouldn't exist.");
     764                 :            :         }
     765                 :            : 
     766         [ +  + ]:       8552 :         if (s->pending)
     767                 :       2068 :                 prioq_remove(s->event->pending, s, &s->pending_index);
     768                 :            : 
     769         [ +  + ]:       8552 :         if (s->prepare)
     770                 :       1960 :                 prioq_remove(s->event->prepare, s, &s->prepare_index);
     771                 :            : 
     772                 :       8552 :         event = s->event;
     773                 :            : 
     774                 :       8552 :         s->type = _SOURCE_EVENT_SOURCE_TYPE_INVALID;
     775                 :       8552 :         s->event = NULL;
     776   [ -  +  +  +  :       8552 :         LIST_REMOVE(sources, event->sources, s);
             +  +  -  + ]
     777                 :       8552 :         event->n_sources--;
     778                 :            : 
     779         [ +  + ]:       8552 :         if (!s->floating)
     780                 :       8540 :                 sd_event_unref(event);
     781                 :            : }
     782                 :            : 
     783                 :       8552 : static void source_free(sd_event_source *s) {
     784         [ -  + ]:       8552 :         assert(s);
     785                 :            : 
     786                 :       8552 :         source_disconnect(s);
     787                 :            : 
     788   [ -  +  #  # ]:       8552 :         if (s->type == SOURCE_IO && s->io.owned)
     789                 :          0 :                 s->io.fd = safe_close(s->io.fd);
     790                 :            : 
     791         [ -  + ]:       8552 :         if (s->destroy_callback)
     792                 :          0 :                 s->destroy_callback(s->userdata);
     793                 :            : 
     794                 :       8552 :         free(s->description);
     795                 :       8552 :         free(s);
     796                 :       8552 : }
     797         [ -  + ]:       8572 : DEFINE_TRIVIAL_CLEANUP_FUNC(sd_event_source*, source_free);
     798                 :            : 
     799                 :    1104520 : static int source_set_pending(sd_event_source *s, bool b) {
     800                 :            :         int r;
     801                 :            : 
     802         [ -  + ]:    1104520 :         assert(s);
     803         [ -  + ]:    1104520 :         assert(s->type != SOURCE_EXIT);
     804                 :            : 
     805         [ +  + ]:    1104520 :         if (s->pending == b)
     806                 :     697698 :                 return 0;
     807                 :            : 
     808                 :     406822 :         s->pending = b;
     809                 :            : 
     810         [ +  + ]:     406822 :         if (b) {
     811                 :     204445 :                 s->pending_iteration = s->event->iteration;
     812                 :            : 
     813                 :     204445 :                 r = prioq_put(s->event->pending, s, &s->pending_index);
     814         [ -  + ]:     204445 :                 if (r < 0) {
     815                 :          0 :                         s->pending = false;
     816                 :          0 :                         return r;
     817                 :            :                 }
     818                 :            :         } else
     819         [ -  + ]:     202377 :                 assert_se(prioq_remove(s->event->pending, s, &s->pending_index));
     820                 :            : 
     821   [ +  +  +  + ]:     406822 :         if (EVENT_SOURCE_IS_TIME(s->type)) {
     822                 :            :                 struct clock_data *d;
     823                 :            : 
     824                 :        304 :                 d = event_get_clock_data(s->event, s->type);
     825         [ -  + ]:        304 :                 assert(d);
     826                 :            : 
     827                 :        304 :                 prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
     828                 :        304 :                 prioq_reshuffle(d->latest, s, &s->time.latest_index);
     829                 :        304 :                 d->needs_rearm = true;
     830                 :            :         }
     831                 :            : 
     832   [ +  +  +  + ]:     406822 :         if (s->type == SOURCE_SIGNAL && !b) {
     833                 :            :                 struct signal_data *d;
     834                 :            : 
     835                 :         20 :                 d = hashmap_get(s->event->signal_data, &s->priority);
     836   [ +  -  +  - ]:         20 :                 if (d && d->current == s)
     837                 :         20 :                         d->current = NULL;
     838                 :            :         }
     839                 :            : 
     840         [ +  + ]:     406822 :         if (s->type == SOURCE_INOTIFY) {
     841                 :            : 
     842         [ -  + ]:     395696 :                 assert(s->inotify.inode_data);
     843         [ -  + ]:     395696 :                 assert(s->inotify.inode_data->inotify_data);
     844                 :            : 
     845         [ +  + ]:     395696 :                 if (b)
     846                 :     197848 :                         s->inotify.inode_data->inotify_data->n_pending ++;
     847                 :            :                 else {
     848         [ -  + ]:     197848 :                         assert(s->inotify.inode_data->inotify_data->n_pending > 0);
     849                 :     197848 :                         s->inotify.inode_data->inotify_data->n_pending --;
     850                 :            :                 }
     851                 :            :         }
     852                 :            : 
     853                 :     406822 :         return 0;
     854                 :            : }
     855                 :            : 
     856                 :       8556 : static sd_event_source *source_new(sd_event *e, bool floating, EventSourceType type) {
     857                 :            :         sd_event_source *s;
     858                 :            : 
     859         [ -  + ]:       8556 :         assert(e);
     860                 :            : 
     861                 :       8556 :         s = new(sd_event_source, 1);
     862         [ -  + ]:       8556 :         if (!s)
     863                 :          0 :                 return NULL;
     864                 :            : 
     865                 :       8556 :         *s = (struct sd_event_source) {
     866                 :            :                 .n_ref = 1,
     867                 :            :                 .event = e,
     868                 :            :                 .floating = floating,
     869                 :            :                 .type = type,
     870                 :            :                 .pending_index = PRIOQ_IDX_NULL,
     871                 :            :                 .prepare_index = PRIOQ_IDX_NULL,
     872                 :            :         };
     873                 :            : 
     874         [ +  + ]:       8556 :         if (!floating)
     875                 :       8544 :                 sd_event_ref(e);
     876                 :            : 
     877   [ -  +  +  + ]:       8556 :         LIST_PREPEND(sources, e->sources, s);
     878                 :       8556 :         e->n_sources++;
     879                 :            : 
     880                 :       8556 :         return s;
     881                 :            : }
     882                 :            : 
     883                 :       2428 : _public_ int sd_event_add_io(
     884                 :            :                 sd_event *e,
     885                 :            :                 sd_event_source **ret,
     886                 :            :                 int fd,
     887                 :            :                 uint32_t events,
     888                 :            :                 sd_event_io_handler_t callback,
     889                 :            :                 void *userdata) {
     890                 :            : 
     891                 :       2428 :         _cleanup_(source_freep) sd_event_source *s = NULL;
     892                 :            :         int r;
     893                 :            : 
     894   [ -  +  -  + ]:       2428 :         assert_return(e, -EINVAL);
     895   [ -  +  -  + ]:       2428 :         assert_return(e = event_resolve(e), -ENOPKG);
     896   [ -  +  -  + ]:       2428 :         assert_return(fd >= 0, -EBADF);
     897   [ -  +  -  + ]:       2428 :         assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL);
     898   [ -  +  -  + ]:       2428 :         assert_return(callback, -EINVAL);
     899   [ -  +  -  + ]:       2428 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
     900   [ -  +  -  + ]:       2428 :         assert_return(!event_pid_changed(e), -ECHILD);
     901                 :            : 
     902                 :       2428 :         s = source_new(e, !ret, SOURCE_IO);
     903         [ -  + ]:       2428 :         if (!s)
     904                 :          0 :                 return -ENOMEM;
     905                 :            : 
     906                 :       2428 :         s->wakeup = WAKEUP_EVENT_SOURCE;
     907                 :       2428 :         s->io.fd = fd;
     908                 :       2428 :         s->io.events = events;
     909                 :       2428 :         s->io.callback = callback;
     910                 :       2428 :         s->userdata = userdata;
     911                 :       2428 :         s->enabled = SD_EVENT_ON;
     912                 :            : 
     913                 :       2428 :         r = source_io_register(s, s->enabled, events);
     914         [ -  + ]:       2428 :         if (r < 0)
     915                 :          0 :                 return r;
     916                 :            : 
     917         [ +  - ]:       2428 :         if (ret)
     918                 :       2428 :                 *ret = s;
     919                 :       2428 :         TAKE_PTR(s);
     920                 :            : 
     921                 :       2428 :         return 0;
     922                 :            : }
     923                 :            : 
     924                 :        238 : static void initialize_perturb(sd_event *e) {
     925                 :        238 :         sd_id128_t bootid = {};
     926                 :            : 
     927                 :            :         /* When we sleep for longer, we try to realign the wakeup to
     928                 :            :            the same time within each minute/second/250ms, so that
     929                 :            :            events all across the system can be coalesced into a single
     930                 :            :            CPU wakeup. However, let's take some system-specific
     931                 :            :            randomness for this value, so that in a network of systems
     932                 :            :            with synced clocks timer events are distributed a
     933                 :            :            bit. Here, we calculate a perturbation usec offset from the
     934                 :            :            boot ID. */
     935                 :            : 
     936         [ +  + ]:        238 :         if (_likely_(e->perturb != USEC_INFINITY))
     937                 :        166 :                 return;
     938                 :            : 
     939         [ +  - ]:         72 :         if (sd_id128_get_boot(&bootid) >= 0)
     940                 :         72 :                 e->perturb = (bootid.qwords[0] ^ bootid.qwords[1]) % USEC_PER_MINUTE;
     941                 :            : }
     942                 :            : 
     943                 :        120 : static int event_setup_timer_fd(
     944                 :            :                 sd_event *e,
     945                 :            :                 struct clock_data *d,
     946                 :            :                 clockid_t clock) {
     947                 :            : 
     948                 :            :         struct epoll_event ev;
     949                 :            :         int r, fd;
     950                 :            : 
     951         [ -  + ]:        120 :         assert(e);
     952         [ -  + ]:        120 :         assert(d);
     953                 :            : 
     954         [ -  + ]:        120 :         if (_likely_(d->fd >= 0))
     955                 :          0 :                 return 0;
     956                 :            : 
     957                 :        120 :         fd = timerfd_create(clock, TFD_NONBLOCK|TFD_CLOEXEC);
     958         [ -  + ]:        120 :         if (fd < 0)
     959                 :          0 :                 return -errno;
     960                 :            : 
     961                 :        120 :         fd = fd_move_above_stdio(fd);
     962                 :            : 
     963                 :        120 :         ev = (struct epoll_event) {
     964                 :            :                 .events = EPOLLIN,
     965                 :            :                 .data.ptr = d,
     966                 :            :         };
     967                 :            : 
     968                 :        120 :         r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, fd, &ev);
     969         [ -  + ]:        120 :         if (r < 0) {
     970                 :          0 :                 safe_close(fd);
     971                 :          0 :                 return -errno;
     972                 :            :         }
     973                 :            : 
     974                 :        120 :         d->fd = fd;
     975                 :        120 :         return 0;
     976                 :            : }
     977                 :            : 
     978                 :          0 : static int time_exit_callback(sd_event_source *s, uint64_t usec, void *userdata) {
     979         [ #  # ]:          0 :         assert(s);
     980                 :            : 
     981                 :          0 :         return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata));
     982                 :            : }
     983                 :            : 
     984                 :       2056 : _public_ int sd_event_add_time(
     985                 :            :                 sd_event *e,
     986                 :            :                 sd_event_source **ret,
     987                 :            :                 clockid_t clock,
     988                 :            :                 uint64_t usec,
     989                 :            :                 uint64_t accuracy,
     990                 :            :                 sd_event_time_handler_t callback,
     991                 :            :                 void *userdata) {
     992                 :            : 
     993                 :            :         EventSourceType type;
     994                 :       2056 :         _cleanup_(source_freep) sd_event_source *s = NULL;
     995                 :            :         struct clock_data *d;
     996                 :            :         int r;
     997                 :            : 
     998   [ -  +  -  + ]:       2056 :         assert_return(e, -EINVAL);
     999   [ -  +  -  + ]:       2056 :         assert_return(e = event_resolve(e), -ENOPKG);
    1000   [ -  +  -  + ]:       2056 :         assert_return(accuracy != (uint64_t) -1, -EINVAL);
    1001   [ -  +  -  + ]:       2056 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
    1002   [ -  +  -  + ]:       2056 :         assert_return(!event_pid_changed(e), -ECHILD);
    1003                 :            : 
    1004         [ -  + ]:       2056 :         if (!clock_supported(clock)) /* Checks whether the kernel supports the clock */
    1005                 :          0 :                 return -EOPNOTSUPP;
    1006                 :            : 
    1007                 :       2056 :         type = clock_to_event_source_type(clock); /* checks whether sd-event supports this clock */
    1008         [ -  + ]:       2056 :         if (type < 0)
    1009                 :          0 :                 return -EOPNOTSUPP;
    1010                 :            : 
    1011         [ -  + ]:       2056 :         if (!callback)
    1012                 :          0 :                 callback = time_exit_callback;
    1013                 :            : 
    1014                 :       2056 :         d = event_get_clock_data(e, type);
    1015         [ -  + ]:       2056 :         assert(d);
    1016                 :            : 
    1017                 :       2056 :         r = prioq_ensure_allocated(&d->earliest, earliest_time_prioq_compare);
    1018         [ -  + ]:       2056 :         if (r < 0)
    1019                 :          0 :                 return r;
    1020                 :            : 
    1021                 :       2056 :         r = prioq_ensure_allocated(&d->latest, latest_time_prioq_compare);
    1022         [ -  + ]:       2056 :         if (r < 0)
    1023                 :          0 :                 return r;
    1024                 :            : 
    1025         [ +  + ]:       2056 :         if (d->fd < 0) {
    1026                 :        120 :                 r = event_setup_timer_fd(e, d, clock);
    1027         [ -  + ]:        120 :                 if (r < 0)
    1028                 :          0 :                         return r;
    1029                 :            :         }
    1030                 :            : 
    1031                 :       2056 :         s = source_new(e, !ret, type);
    1032         [ -  + ]:       2056 :         if (!s)
    1033                 :          0 :                 return -ENOMEM;
    1034                 :            : 
    1035                 :       2056 :         s->time.next = usec;
    1036         [ +  + ]:       2056 :         s->time.accuracy = accuracy == 0 ? DEFAULT_ACCURACY_USEC : accuracy;
    1037                 :       2056 :         s->time.callback = callback;
    1038                 :       2056 :         s->time.earliest_index = s->time.latest_index = PRIOQ_IDX_NULL;
    1039                 :       2056 :         s->userdata = userdata;
    1040                 :       2056 :         s->enabled = SD_EVENT_ONESHOT;
    1041                 :            : 
    1042                 :       2056 :         d->needs_rearm = true;
    1043                 :            : 
    1044                 :       2056 :         r = prioq_put(d->earliest, s, &s->time.earliest_index);
    1045         [ -  + ]:       2056 :         if (r < 0)
    1046                 :          0 :                 return r;
    1047                 :            : 
    1048                 :       2056 :         r = prioq_put(d->latest, s, &s->time.latest_index);
    1049         [ -  + ]:       2056 :         if (r < 0)
    1050                 :          0 :                 return r;
    1051                 :            : 
    1052         [ +  - ]:       2056 :         if (ret)
    1053                 :       2056 :                 *ret = s;
    1054                 :       2056 :         TAKE_PTR(s);
    1055                 :            : 
    1056                 :       2056 :         return 0;
    1057                 :            : }
    1058                 :            : 
    1059                 :          0 : static int signal_exit_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
    1060         [ #  # ]:          0 :         assert(s);
    1061                 :            : 
    1062                 :          0 :         return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata));
    1063                 :            : }
    1064                 :            : 
    1065                 :         36 : _public_ int sd_event_add_signal(
    1066                 :            :                 sd_event *e,
    1067                 :            :                 sd_event_source **ret,
    1068                 :            :                 int sig,
    1069                 :            :                 sd_event_signal_handler_t callback,
    1070                 :            :                 void *userdata) {
    1071                 :            : 
    1072                 :         36 :         _cleanup_(source_freep) sd_event_source *s = NULL;
    1073                 :            :         struct signal_data *d;
    1074                 :            :         sigset_t ss;
    1075                 :            :         int r;
    1076                 :            : 
    1077   [ -  +  -  + ]:         36 :         assert_return(e, -EINVAL);
    1078   [ -  +  -  + ]:         36 :         assert_return(e = event_resolve(e), -ENOPKG);
    1079   [ -  +  -  + ]:         36 :         assert_return(SIGNAL_VALID(sig), -EINVAL);
    1080   [ -  +  -  + ]:         36 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
    1081   [ -  +  -  + ]:         36 :         assert_return(!event_pid_changed(e), -ECHILD);
    1082                 :            : 
    1083         [ +  + ]:         36 :         if (!callback)
    1084                 :         20 :                 callback = signal_exit_callback;
    1085                 :            : 
    1086                 :         36 :         r = pthread_sigmask(SIG_SETMASK, NULL, &ss);
    1087         [ -  + ]:         36 :         if (r != 0)
    1088                 :          0 :                 return -r;
    1089                 :            : 
    1090         [ +  + ]:         36 :         if (!sigismember(&ss, sig))
    1091                 :         16 :                 return -EBUSY;
    1092                 :            : 
    1093         [ +  + ]:         20 :         if (!e->signal_sources) {
    1094                 :          8 :                 e->signal_sources = new0(sd_event_source*, _NSIG);
    1095         [ -  + ]:          8 :                 if (!e->signal_sources)
    1096                 :          0 :                         return -ENOMEM;
    1097         [ -  + ]:         12 :         } else if (e->signal_sources[sig])
    1098                 :          0 :                 return -EBUSY;
    1099                 :            : 
    1100                 :         20 :         s = source_new(e, !ret, SOURCE_SIGNAL);
    1101         [ -  + ]:         20 :         if (!s)
    1102                 :          0 :                 return -ENOMEM;
    1103                 :            : 
    1104                 :         20 :         s->signal.sig = sig;
    1105                 :         20 :         s->signal.callback = callback;
    1106                 :         20 :         s->userdata = userdata;
    1107                 :         20 :         s->enabled = SD_EVENT_ON;
    1108                 :            : 
    1109                 :         20 :         e->signal_sources[sig] = s;
    1110                 :            : 
    1111                 :         20 :         r = event_make_signal_data(e, sig, &d);
    1112         [ -  + ]:         20 :         if (r < 0)
    1113                 :          0 :                 return r;
    1114                 :            : 
    1115                 :            :         /* Use the signal name as description for the event source by default */
    1116                 :         20 :         (void) sd_event_source_set_description(s, signal_to_string(sig));
    1117                 :            : 
    1118         [ +  + ]:         20 :         if (ret)
    1119                 :         16 :                 *ret = s;
    1120                 :         20 :         TAKE_PTR(s);
    1121                 :            : 
    1122                 :         20 :         return 0;
    1123                 :            : }
    1124                 :            : 
    1125                 :          4 : _public_ int sd_event_add_child(
    1126                 :            :                 sd_event *e,
    1127                 :            :                 sd_event_source **ret,
    1128                 :            :                 pid_t pid,
    1129                 :            :                 int options,
    1130                 :            :                 sd_event_child_handler_t callback,
    1131                 :            :                 void *userdata) {
    1132                 :            : 
    1133                 :          4 :         _cleanup_(source_freep) sd_event_source *s = NULL;
    1134                 :            :         int r;
    1135                 :            : 
    1136   [ -  +  -  + ]:          4 :         assert_return(e, -EINVAL);
    1137   [ -  +  -  + ]:          4 :         assert_return(e = event_resolve(e), -ENOPKG);
    1138   [ -  +  -  + ]:          4 :         assert_return(pid > 1, -EINVAL);
    1139   [ -  +  -  + ]:          4 :         assert_return(!(options & ~(WEXITED|WSTOPPED|WCONTINUED)), -EINVAL);
    1140   [ -  +  -  + ]:          4 :         assert_return(options != 0, -EINVAL);
    1141   [ -  +  -  + ]:          4 :         assert_return(callback, -EINVAL);
    1142   [ -  +  -  + ]:          4 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
    1143   [ -  +  -  + ]:          4 :         assert_return(!event_pid_changed(e), -ECHILD);
    1144                 :            : 
    1145                 :          4 :         r = hashmap_ensure_allocated(&e->child_sources, NULL);
    1146         [ -  + ]:          4 :         if (r < 0)
    1147                 :          0 :                 return r;
    1148                 :            : 
    1149         [ -  + ]:          4 :         if (hashmap_contains(e->child_sources, PID_TO_PTR(pid)))
    1150                 :          0 :                 return -EBUSY;
    1151                 :            : 
    1152                 :          4 :         s = source_new(e, !ret, SOURCE_CHILD);
    1153         [ -  + ]:          4 :         if (!s)
    1154                 :          0 :                 return -ENOMEM;
    1155                 :            : 
    1156                 :          4 :         s->child.pid = pid;
    1157                 :          4 :         s->child.options = options;
    1158                 :          4 :         s->child.callback = callback;
    1159                 :          4 :         s->userdata = userdata;
    1160                 :          4 :         s->enabled = SD_EVENT_ONESHOT;
    1161                 :            : 
    1162                 :          4 :         r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s);
    1163         [ -  + ]:          4 :         if (r < 0)
    1164                 :          0 :                 return r;
    1165                 :            : 
    1166                 :          4 :         e->n_enabled_child_sources++;
    1167                 :            : 
    1168                 :          4 :         r = event_make_signal_data(e, SIGCHLD, NULL);
    1169         [ -  + ]:          4 :         if (r < 0) {
    1170                 :          0 :                 e->n_enabled_child_sources--;
    1171                 :          0 :                 return r;
    1172                 :            :         }
    1173                 :            : 
    1174                 :          4 :         e->need_process_child = true;
    1175                 :            : 
    1176         [ +  - ]:          4 :         if (ret)
    1177                 :          4 :                 *ret = s;
    1178                 :          4 :         TAKE_PTR(s);
    1179                 :            : 
    1180                 :          4 :         return 0;
    1181                 :            : }
    1182                 :            : 
    1183                 :       2064 : _public_ int sd_event_add_defer(
    1184                 :            :                 sd_event *e,
    1185                 :            :                 sd_event_source **ret,
    1186                 :            :                 sd_event_handler_t callback,
    1187                 :            :                 void *userdata) {
    1188                 :            : 
    1189                 :       2064 :         _cleanup_(source_freep) sd_event_source *s = NULL;
    1190                 :            :         int r;
    1191                 :            : 
    1192   [ -  +  -  + ]:       2064 :         assert_return(e, -EINVAL);
    1193   [ -  +  -  + ]:       2064 :         assert_return(e = event_resolve(e), -ENOPKG);
    1194   [ -  +  -  + ]:       2064 :         assert_return(callback, -EINVAL);
    1195   [ -  +  -  + ]:       2064 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
    1196   [ -  +  -  + ]:       2064 :         assert_return(!event_pid_changed(e), -ECHILD);
    1197                 :            : 
    1198                 :       2064 :         s = source_new(e, !ret, SOURCE_DEFER);
    1199         [ -  + ]:       2064 :         if (!s)
    1200                 :          0 :                 return -ENOMEM;
    1201                 :            : 
    1202                 :       2064 :         s->defer.callback = callback;
    1203                 :       2064 :         s->userdata = userdata;
    1204                 :       2064 :         s->enabled = SD_EVENT_ONESHOT;
    1205                 :            : 
    1206                 :       2064 :         r = source_set_pending(s, true);
    1207         [ -  + ]:       2064 :         if (r < 0)
    1208                 :          0 :                 return r;
    1209                 :            : 
    1210         [ +  - ]:       2064 :         if (ret)
    1211                 :       2064 :                 *ret = s;
    1212                 :       2064 :         TAKE_PTR(s);
    1213                 :            : 
    1214                 :       2064 :         return 0;
    1215                 :            : }
    1216                 :            : 
    1217                 :          8 : _public_ int sd_event_add_post(
    1218                 :            :                 sd_event *e,
    1219                 :            :                 sd_event_source **ret,
    1220                 :            :                 sd_event_handler_t callback,
    1221                 :            :                 void *userdata) {
    1222                 :            : 
    1223                 :          8 :         _cleanup_(source_freep) sd_event_source *s = NULL;
    1224                 :            :         int r;
    1225                 :            : 
    1226   [ -  +  -  + ]:          8 :         assert_return(e, -EINVAL);
    1227   [ -  +  -  + ]:          8 :         assert_return(e = event_resolve(e), -ENOPKG);
    1228   [ -  +  -  + ]:          8 :         assert_return(callback, -EINVAL);
    1229   [ -  +  -  + ]:          8 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
    1230   [ -  +  -  + ]:          8 :         assert_return(!event_pid_changed(e), -ECHILD);
    1231                 :            : 
    1232                 :          8 :         r = set_ensure_allocated(&e->post_sources, NULL);
    1233         [ -  + ]:          8 :         if (r < 0)
    1234                 :          0 :                 return r;
    1235                 :            : 
    1236                 :          8 :         s = source_new(e, !ret, SOURCE_POST);
    1237         [ -  + ]:          8 :         if (!s)
    1238                 :          0 :                 return -ENOMEM;
    1239                 :            : 
    1240                 :          8 :         s->post.callback = callback;
    1241                 :          8 :         s->userdata = userdata;
    1242                 :          8 :         s->enabled = SD_EVENT_ON;
    1243                 :            : 
    1244                 :          8 :         r = set_put(e->post_sources, s);
    1245         [ -  + ]:          8 :         if (r < 0)
    1246                 :          0 :                 return r;
    1247                 :            : 
    1248         [ -  + ]:          8 :         if (ret)
    1249                 :          0 :                 *ret = s;
    1250                 :          8 :         TAKE_PTR(s);
    1251                 :            : 
    1252                 :          8 :         return 0;
    1253                 :            : }
    1254                 :            : 
    1255                 :       1944 : _public_ int sd_event_add_exit(
    1256                 :            :                 sd_event *e,
    1257                 :            :                 sd_event_source **ret,
    1258                 :            :                 sd_event_handler_t callback,
    1259                 :            :                 void *userdata) {
    1260                 :            : 
    1261                 :       1944 :         _cleanup_(source_freep) sd_event_source *s = NULL;
    1262                 :            :         int r;
    1263                 :            : 
    1264   [ -  +  -  + ]:       1944 :         assert_return(e, -EINVAL);
    1265   [ -  +  -  + ]:       1944 :         assert_return(e = event_resolve(e), -ENOPKG);
    1266   [ -  +  -  + ]:       1944 :         assert_return(callback, -EINVAL);
    1267   [ -  +  -  + ]:       1944 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
    1268   [ -  +  -  + ]:       1944 :         assert_return(!event_pid_changed(e), -ECHILD);
    1269                 :            : 
    1270                 :       1944 :         r = prioq_ensure_allocated(&e->exit, exit_prioq_compare);
    1271         [ -  + ]:       1944 :         if (r < 0)
    1272                 :          0 :                 return r;
    1273                 :            : 
    1274                 :       1944 :         s = source_new(e, !ret, SOURCE_EXIT);
    1275         [ -  + ]:       1944 :         if (!s)
    1276                 :          0 :                 return -ENOMEM;
    1277                 :            : 
    1278                 :       1944 :         s->exit.callback = callback;
    1279                 :       1944 :         s->userdata = userdata;
    1280                 :       1944 :         s->exit.prioq_index = PRIOQ_IDX_NULL;
    1281                 :       1944 :         s->enabled = SD_EVENT_ONESHOT;
    1282                 :            : 
    1283                 :       1944 :         r = prioq_put(s->event->exit, s, &s->exit.prioq_index);
    1284         [ -  + ]:       1944 :         if (r < 0)
    1285                 :          0 :                 return r;
    1286                 :            : 
    1287         [ +  - ]:       1944 :         if (ret)
    1288                 :       1944 :                 *ret = s;
    1289                 :       1944 :         TAKE_PTR(s);
    1290                 :            : 
    1291                 :       1944 :         return 0;
    1292                 :            : }
    1293                 :            : 
    1294                 :         24 : static void event_free_inotify_data(sd_event *e, struct inotify_data *d) {
    1295         [ -  + ]:         24 :         assert(e);
    1296                 :            : 
    1297         [ -  + ]:         24 :         if (!d)
    1298                 :          0 :                 return;
    1299                 :            : 
    1300         [ -  + ]:         24 :         assert(hashmap_isempty(d->inodes));
    1301         [ -  + ]:         24 :         assert(hashmap_isempty(d->wd));
    1302                 :            : 
    1303         [ +  + ]:         24 :         if (d->buffer_filled > 0)
    1304   [ -  +  -  +  :          4 :                 LIST_REMOVE(buffered, e->inotify_data_buffered, d);
             -  +  -  + ]
    1305                 :            : 
    1306                 :         24 :         hashmap_free(d->inodes);
    1307                 :         24 :         hashmap_free(d->wd);
    1308                 :            : 
    1309         [ -  + ]:         24 :         assert_se(hashmap_remove(e->inotify_data, &d->priority) == d);
    1310                 :            : 
    1311         [ +  - ]:         24 :         if (d->fd >= 0) {
    1312         [ -  + ]:         24 :                 if (epoll_ctl(e->epoll_fd, EPOLL_CTL_DEL, d->fd, NULL) < 0)
    1313         [ #  # ]:          0 :                         log_debug_errno(errno, "Failed to remove inotify fd from epoll, ignoring: %m");
    1314                 :            : 
    1315                 :         24 :                 safe_close(d->fd);
    1316                 :            :         }
    1317                 :         24 :         free(d);
    1318                 :            : }
    1319                 :            : 
    1320                 :         56 : static int event_make_inotify_data(
    1321                 :            :                 sd_event *e,
    1322                 :            :                 int64_t priority,
    1323                 :            :                 struct inotify_data **ret) {
    1324                 :            : 
    1325                 :         56 :         _cleanup_close_ int fd = -1;
    1326                 :            :         struct inotify_data *d;
    1327                 :            :         struct epoll_event ev;
    1328                 :            :         int r;
    1329                 :            : 
    1330         [ -  + ]:         56 :         assert(e);
    1331                 :            : 
    1332                 :         56 :         d = hashmap_get(e->inotify_data, &priority);
    1333         [ +  + ]:         56 :         if (d) {
    1334         [ +  - ]:         32 :                 if (ret)
    1335                 :         32 :                         *ret = d;
    1336                 :         32 :                 return 0;
    1337                 :            :         }
    1338                 :            : 
    1339                 :         24 :         fd = inotify_init1(IN_NONBLOCK|O_CLOEXEC);
    1340         [ -  + ]:         24 :         if (fd < 0)
    1341                 :          0 :                 return -errno;
    1342                 :            : 
    1343                 :         24 :         fd = fd_move_above_stdio(fd);
    1344                 :            : 
    1345                 :         24 :         r = hashmap_ensure_allocated(&e->inotify_data, &uint64_hash_ops);
    1346         [ -  + ]:         24 :         if (r < 0)
    1347                 :          0 :                 return r;
    1348                 :            : 
    1349                 :         24 :         d = new(struct inotify_data, 1);
    1350         [ -  + ]:         24 :         if (!d)
    1351                 :          0 :                 return -ENOMEM;
    1352                 :            : 
    1353                 :         24 :         *d = (struct inotify_data) {
    1354                 :            :                 .wakeup = WAKEUP_INOTIFY_DATA,
    1355                 :         24 :                 .fd = TAKE_FD(fd),
    1356                 :            :                 .priority = priority,
    1357                 :            :         };
    1358                 :            : 
    1359                 :         24 :         r = hashmap_put(e->inotify_data, &d->priority, d);
    1360         [ -  + ]:         24 :         if (r < 0) {
    1361                 :          0 :                 d->fd = safe_close(d->fd);
    1362                 :          0 :                 free(d);
    1363                 :          0 :                 return r;
    1364                 :            :         }
    1365                 :            : 
    1366                 :         24 :         ev = (struct epoll_event) {
    1367                 :            :                 .events = EPOLLIN,
    1368                 :            :                 .data.ptr = d,
    1369                 :            :         };
    1370                 :            : 
    1371         [ -  + ]:         24 :         if (epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, d->fd, &ev) < 0) {
    1372                 :          0 :                 r = -errno;
    1373                 :          0 :                 d->fd = safe_close(d->fd); /* let's close this ourselves, as event_free_inotify_data() would otherwise
    1374                 :            :                                             * remove the fd from the epoll first, which we don't want as we couldn't
    1375                 :            :                                             * add it in the first place. */
    1376                 :          0 :                 event_free_inotify_data(e, d);
    1377                 :          0 :                 return r;
    1378                 :            :         }
    1379                 :            : 
    1380         [ +  - ]:         24 :         if (ret)
    1381                 :         24 :                 *ret = d;
    1382                 :            : 
    1383                 :         24 :         return 1;
    1384                 :            : }
    1385                 :            : 
    1386                 :         68 : static int inode_data_compare(const struct inode_data *x, const struct inode_data *y) {
    1387                 :            :         int r;
    1388                 :            : 
    1389         [ -  + ]:         68 :         assert(x);
    1390         [ -  + ]:         68 :         assert(y);
    1391                 :            : 
    1392         [ +  - ]:         68 :         r = CMP(x->dev, y->dev);
    1393         [ -  + ]:         68 :         if (r != 0)
    1394                 :          0 :                 return r;
    1395                 :            : 
    1396         [ +  + ]:         68 :         return CMP(x->ino, y->ino);
    1397                 :            : }
    1398                 :            : 
    1399                 :         96 : static void inode_data_hash_func(const struct inode_data *d, struct siphash *state) {
    1400         [ -  + ]:         96 :         assert(d);
    1401                 :            : 
    1402                 :         96 :         siphash24_compress(&d->dev, sizeof(d->dev), state);
    1403                 :         96 :         siphash24_compress(&d->ino, sizeof(d->ino), state);
    1404                 :         96 : }
    1405                 :            : 
    1406                 :            : DEFINE_PRIVATE_HASH_OPS(inode_data_hash_ops, struct inode_data, inode_data_hash_func, inode_data_compare);
    1407                 :            : 
    1408                 :         32 : static void event_free_inode_data(
    1409                 :            :                 sd_event *e,
    1410                 :            :                 struct inode_data *d) {
    1411                 :            : 
    1412         [ -  + ]:         32 :         assert(e);
    1413                 :            : 
    1414         [ -  + ]:         32 :         if (!d)
    1415                 :          0 :                 return;
    1416                 :            : 
    1417         [ -  + ]:         32 :         assert(!d->event_sources);
    1418                 :            : 
    1419         [ +  + ]:         32 :         if (d->fd >= 0) {
    1420   [ -  +  +  -  :          8 :                 LIST_REMOVE(to_close, e->inode_data_to_close, d);
             -  +  -  + ]
    1421                 :          8 :                 safe_close(d->fd);
    1422                 :            :         }
    1423                 :            : 
    1424         [ +  - ]:         32 :         if (d->inotify_data) {
    1425                 :            : 
    1426         [ +  + ]:         32 :                 if (d->wd >= 0) {
    1427         [ +  - ]:         28 :                         if (d->inotify_data->fd >= 0) {
    1428                 :            :                                 /* So here's a problem. At the time this runs the watch descriptor might already be
    1429                 :            :                                  * invalidated, because an IN_IGNORED event might be queued right the moment we enter
    1430                 :            :                                  * the syscall. Hence, whenever we get EINVAL, ignore it entirely, since it's a very
    1431                 :            :                                  * likely case to happen. */
    1432                 :            : 
    1433   [ +  +  -  + ]:         28 :                                 if (inotify_rm_watch(d->inotify_data->fd, d->wd) < 0 && errno != EINVAL)
    1434         [ #  # ]:          0 :                                         log_debug_errno(errno, "Failed to remove watch descriptor %i from inotify, ignoring: %m", d->wd);
    1435                 :            :                         }
    1436                 :            : 
    1437         [ -  + ]:         28 :                         assert_se(hashmap_remove(d->inotify_data->wd, INT_TO_PTR(d->wd)) == d);
    1438                 :            :                 }
    1439                 :            : 
    1440         [ -  + ]:         32 :                 assert_se(hashmap_remove(d->inotify_data->inodes, d) == d);
    1441                 :            :         }
    1442                 :            : 
    1443                 :         32 :         free(d);
    1444                 :            : }
    1445                 :            : 
    1446                 :         56 : static void event_gc_inode_data(
    1447                 :            :                 sd_event *e,
    1448                 :            :                 struct inode_data *d) {
    1449                 :            : 
    1450                 :            :         struct inotify_data *inotify_data;
    1451                 :            : 
    1452         [ -  + ]:         56 :         assert(e);
    1453                 :            : 
    1454         [ -  + ]:         56 :         if (!d)
    1455                 :          0 :                 return;
    1456                 :            : 
    1457         [ +  + ]:         56 :         if (d->event_sources)
    1458                 :         24 :                 return;
    1459                 :            : 
    1460                 :         32 :         inotify_data = d->inotify_data;
    1461                 :         32 :         event_free_inode_data(e, d);
    1462                 :            : 
    1463   [ +  -  +  + ]:         32 :         if (inotify_data && hashmap_isempty(inotify_data->inodes))
    1464                 :         24 :                 event_free_inotify_data(e, inotify_data);
    1465                 :            : }
    1466                 :            : 
    1467                 :         56 : static int event_make_inode_data(
    1468                 :            :                 sd_event *e,
    1469                 :            :                 struct inotify_data *inotify_data,
    1470                 :            :                 dev_t dev,
    1471                 :            :                 ino_t ino,
    1472                 :            :                 struct inode_data **ret) {
    1473                 :            : 
    1474                 :            :         struct inode_data *d, key;
    1475                 :            :         int r;
    1476                 :            : 
    1477         [ -  + ]:         56 :         assert(e);
    1478         [ -  + ]:         56 :         assert(inotify_data);
    1479                 :            : 
    1480                 :         56 :         key = (struct inode_data) {
    1481                 :            :                 .ino = ino,
    1482                 :            :                 .dev = dev,
    1483                 :            :         };
    1484                 :            : 
    1485                 :         56 :         d = hashmap_get(inotify_data->inodes, &key);
    1486         [ +  + ]:         56 :         if (d) {
    1487         [ +  - ]:         24 :                 if (ret)
    1488                 :         24 :                         *ret = d;
    1489                 :            : 
    1490                 :         24 :                 return 0;
    1491                 :            :         }
    1492                 :            : 
    1493                 :         32 :         r = hashmap_ensure_allocated(&inotify_data->inodes, &inode_data_hash_ops);
    1494         [ -  + ]:         32 :         if (r < 0)
    1495                 :          0 :                 return r;
    1496                 :            : 
    1497                 :         32 :         d = new(struct inode_data, 1);
    1498         [ -  + ]:         32 :         if (!d)
    1499                 :          0 :                 return -ENOMEM;
    1500                 :            : 
    1501                 :         32 :         *d = (struct inode_data) {
    1502                 :            :                 .dev = dev,
    1503                 :            :                 .ino = ino,
    1504                 :            :                 .wd = -1,
    1505                 :            :                 .fd = -1,
    1506                 :            :                 .inotify_data = inotify_data,
    1507                 :            :         };
    1508                 :            : 
    1509                 :         32 :         r = hashmap_put(inotify_data->inodes, d, d);
    1510         [ -  + ]:         32 :         if (r < 0) {
    1511                 :          0 :                 free(d);
    1512                 :          0 :                 return r;
    1513                 :            :         }
    1514                 :            : 
    1515         [ +  - ]:         32 :         if (ret)
    1516                 :         32 :                 *ret = d;
    1517                 :            : 
    1518                 :         32 :         return 1;
    1519                 :            : }
    1520                 :            : 
    1521                 :         56 : static uint32_t inode_data_determine_mask(struct inode_data *d) {
    1522                 :         56 :         bool excl_unlink = true;
    1523                 :         56 :         uint32_t combined = 0;
    1524                 :            :         sd_event_source *s;
    1525                 :            : 
    1526         [ -  + ]:         56 :         assert(d);
    1527                 :            : 
    1528                 :            :         /* Combines the watch masks of all event sources watching this inode. We generally just OR them together, but
    1529                 :            :          * the IN_EXCL_UNLINK flag is ANDed instead.
    1530                 :            :          *
    1531                 :            :          * Note that we add all sources to the mask here, regardless whether enabled, disabled or oneshot. That's
    1532                 :            :          * because we cannot change the mask anymore after the event source was created once, since the kernel has no
    1533                 :            :          * API for that. Hence we need to subscribe to the maximum mask we ever might be interested in, and suppress
    1534                 :            :          * events we don't care for client-side. */
    1535                 :            : 
    1536         [ +  + ]:        144 :         LIST_FOREACH(inotify.by_inode_data, s, d->event_sources) {
    1537                 :            : 
    1538         [ +  + ]:         88 :                 if ((s->inotify.mask & IN_EXCL_UNLINK) == 0)
    1539                 :         72 :                         excl_unlink = false;
    1540                 :            : 
    1541                 :         88 :                 combined |= s->inotify.mask;
    1542                 :            :         }
    1543                 :            : 
    1544         [ +  + ]:         56 :         return (combined & ~(IN_ONESHOT|IN_DONT_FOLLOW|IN_ONLYDIR|IN_EXCL_UNLINK)) | (excl_unlink ? IN_EXCL_UNLINK : 0);
    1545                 :            : }
    1546                 :            : 
    1547                 :         56 : static int inode_data_realize_watch(sd_event *e, struct inode_data *d) {
    1548                 :            :         uint32_t combined_mask;
    1549                 :            :         int wd, r;
    1550                 :            : 
    1551         [ -  + ]:         56 :         assert(d);
    1552         [ -  + ]:         56 :         assert(d->fd >= 0);
    1553                 :            : 
    1554                 :         56 :         combined_mask = inode_data_determine_mask(d);
    1555                 :            : 
    1556   [ +  +  +  + ]:         56 :         if (d->wd >= 0 && combined_mask == d->combined_mask)
    1557                 :         16 :                 return 0;
    1558                 :            : 
    1559                 :         40 :         r = hashmap_ensure_allocated(&d->inotify_data->wd, NULL);
    1560         [ -  + ]:         40 :         if (r < 0)
    1561                 :          0 :                 return r;
    1562                 :            : 
    1563                 :         40 :         wd = inotify_add_watch_fd(d->inotify_data->fd, d->fd, combined_mask);
    1564         [ -  + ]:         40 :         if (wd < 0)
    1565                 :          0 :                 return -errno;
    1566                 :            : 
    1567         [ +  + ]:         40 :         if (d->wd < 0) {
    1568                 :         32 :                 r = hashmap_put(d->inotify_data->wd, INT_TO_PTR(wd), d);
    1569         [ -  + ]:         32 :                 if (r < 0) {
    1570                 :          0 :                         (void) inotify_rm_watch(d->inotify_data->fd, wd);
    1571                 :          0 :                         return r;
    1572                 :            :                 }
    1573                 :            : 
    1574                 :         32 :                 d->wd = wd;
    1575                 :            : 
    1576         [ -  + ]:          8 :         } else if (d->wd != wd) {
    1577                 :            : 
    1578         [ #  # ]:          0 :                 log_debug("Weird, the watch descriptor we already knew for this inode changed?");
    1579                 :          0 :                 (void) inotify_rm_watch(d->fd, wd);
    1580                 :          0 :                 return -EINVAL;
    1581                 :            :         }
    1582                 :            : 
    1583                 :         40 :         d->combined_mask = combined_mask;
    1584                 :         40 :         return 1;
    1585                 :            : }
    1586                 :            : 
    1587                 :         32 : _public_ int sd_event_add_inotify(
    1588                 :            :                 sd_event *e,
    1589                 :            :                 sd_event_source **ret,
    1590                 :            :                 const char *path,
    1591                 :            :                 uint32_t mask,
    1592                 :            :                 sd_event_inotify_handler_t callback,
    1593                 :            :                 void *userdata) {
    1594                 :            : 
    1595                 :         32 :         struct inotify_data *inotify_data = NULL;
    1596                 :         32 :         struct inode_data *inode_data = NULL;
    1597                 :         32 :         _cleanup_close_ int fd = -1;
    1598                 :         32 :         _cleanup_(source_freep) sd_event_source *s = NULL;
    1599                 :            :         struct stat st;
    1600                 :            :         int r;
    1601                 :            : 
    1602   [ -  +  -  + ]:         32 :         assert_return(e, -EINVAL);
    1603   [ -  +  -  + ]:         32 :         assert_return(e = event_resolve(e), -ENOPKG);
    1604   [ -  +  -  + ]:         32 :         assert_return(path, -EINVAL);
    1605   [ -  +  -  + ]:         32 :         assert_return(callback, -EINVAL);
    1606   [ -  +  -  + ]:         32 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
    1607   [ -  +  -  + ]:         32 :         assert_return(!event_pid_changed(e), -ECHILD);
    1608                 :            : 
    1609                 :            :         /* Refuse IN_MASK_ADD since we coalesce watches on the same inode, and hence really don't want to merge
    1610                 :            :          * masks. Or in other words, this whole code exists only to manage IN_MASK_ADD type operations for you, hence
    1611                 :            :          * the user can't use them for us. */
    1612         [ -  + ]:         32 :         if (mask & IN_MASK_ADD)
    1613                 :          0 :                 return -EINVAL;
    1614                 :            : 
    1615                 :         96 :         fd = open(path, O_PATH|O_CLOEXEC|
    1616                 :         32 :                   (mask & IN_ONLYDIR ? O_DIRECTORY : 0)|
    1617                 :         32 :                   (mask & IN_DONT_FOLLOW ? O_NOFOLLOW : 0));
    1618         [ -  + ]:         32 :         if (fd < 0)
    1619                 :          0 :                 return -errno;
    1620                 :            : 
    1621         [ -  + ]:         32 :         if (fstat(fd, &st) < 0)
    1622                 :          0 :                 return -errno;
    1623                 :            : 
    1624                 :         32 :         s = source_new(e, !ret, SOURCE_INOTIFY);
    1625         [ -  + ]:         32 :         if (!s)
    1626                 :          0 :                 return -ENOMEM;
    1627                 :            : 
    1628         [ -  + ]:         32 :         s->enabled = mask & IN_ONESHOT ? SD_EVENT_ONESHOT : SD_EVENT_ON;
    1629                 :         32 :         s->inotify.mask = mask;
    1630                 :         32 :         s->inotify.callback = callback;
    1631                 :         32 :         s->userdata = userdata;
    1632                 :            : 
    1633                 :            :         /* Allocate an inotify object for this priority, and an inode object within it */
    1634                 :         32 :         r = event_make_inotify_data(e, SD_EVENT_PRIORITY_NORMAL, &inotify_data);
    1635         [ -  + ]:         32 :         if (r < 0)
    1636                 :          0 :                 return r;
    1637                 :            : 
    1638                 :         32 :         r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data);
    1639         [ -  + ]:         32 :         if (r < 0) {
    1640                 :          0 :                 event_free_inotify_data(e, inotify_data);
    1641                 :          0 :                 return r;
    1642                 :            :         }
    1643                 :            : 
    1644                 :            :         /* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of
    1645                 :            :          * the event source, until then, for which we need the original inode. */
    1646         [ +  + ]:         32 :         if (inode_data->fd < 0) {
    1647                 :         16 :                 inode_data->fd = TAKE_FD(fd);
    1648   [ -  +  +  + ]:         16 :                 LIST_PREPEND(to_close, e->inode_data_to_close, inode_data);
    1649                 :            :         }
    1650                 :            : 
    1651                 :            :         /* Link our event source to the inode data object */
    1652   [ -  +  +  + ]:         32 :         LIST_PREPEND(inotify.by_inode_data, inode_data->event_sources, s);
    1653                 :         32 :         s->inotify.inode_data = inode_data;
    1654                 :            : 
    1655                 :            :         /* Actually realize the watch now */
    1656                 :         32 :         r = inode_data_realize_watch(e, inode_data);
    1657         [ -  + ]:         32 :         if (r < 0)
    1658                 :          0 :                 return r;
    1659                 :            : 
    1660                 :         32 :         (void) sd_event_source_set_description(s, path);
    1661                 :            : 
    1662         [ +  - ]:         32 :         if (ret)
    1663                 :         32 :                 *ret = s;
    1664                 :         32 :         TAKE_PTR(s);
    1665                 :            : 
    1666                 :         32 :         return 0;
    1667                 :            : }
    1668                 :            : 
    1669                 :       8552 : static sd_event_source* event_source_free(sd_event_source *s) {
    1670         [ -  + ]:       8552 :         if (!s)
    1671                 :          0 :                 return NULL;
    1672                 :            : 
    1673                 :            :         /* Here's a special hack: when we are called from a
    1674                 :            :          * dispatch handler we won't free the event source
    1675                 :            :          * immediately, but we will detach the fd from the
    1676                 :            :          * epoll. This way it is safe for the caller to unref
    1677                 :            :          * the event source and immediately close the fd, but
    1678                 :            :          * we still retain a valid event source object after
    1679                 :            :          * the callback. */
    1680                 :            : 
    1681         [ +  + ]:       8552 :         if (s->dispatching) {
    1682         [ +  + ]:       1944 :                 if (s->type == SOURCE_IO)
    1683                 :         36 :                         source_io_unregister(s);
    1684                 :            : 
    1685                 :       1944 :                 source_disconnect(s);
    1686                 :            :         } else
    1687                 :       6608 :                 source_free(s);
    1688                 :            : 
    1689                 :       8552 :         return NULL;
    1690                 :            : }
    1691                 :            : 
    1692   [ +  +  -  +  :      21640 : DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_event_source, sd_event_source, event_source_free);
                   -  + ]
    1693                 :            : 
    1694                 :       8668 : _public_ int sd_event_source_set_description(sd_event_source *s, const char *description) {
    1695   [ -  +  -  + ]:       8668 :         assert_return(s, -EINVAL);
    1696   [ -  +  -  + ]:       8668 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1697                 :            : 
    1698                 :       8668 :         return free_and_strdup(&s->description, description);
    1699                 :            : }
    1700                 :            : 
    1701                 :     197836 : _public_ int sd_event_source_get_description(sd_event_source *s, const char **description) {
    1702   [ -  +  -  + ]:     197836 :         assert_return(s, -EINVAL);
    1703   [ -  +  -  + ]:     197836 :         assert_return(description, -EINVAL);
    1704   [ -  +  -  + ]:     197836 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1705                 :            : 
    1706         [ -  + ]:     197836 :         if (!s->description)
    1707                 :          0 :                 return -ENXIO;
    1708                 :            : 
    1709                 :     197836 :         *description = s->description;
    1710                 :     197836 :         return 0;
    1711                 :            : }
    1712                 :            : 
    1713                 :         24 : _public_ sd_event *sd_event_source_get_event(sd_event_source *s) {
    1714   [ -  +  -  + ]:         24 :         assert_return(s, NULL);
    1715                 :            : 
    1716                 :         24 :         return s->event;
    1717                 :            : }
    1718                 :            : 
    1719                 :          0 : _public_ int sd_event_source_get_pending(sd_event_source *s) {
    1720   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    1721   [ #  #  #  # ]:          0 :         assert_return(s->type != SOURCE_EXIT, -EDOM);
    1722   [ #  #  #  # ]:          0 :         assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
    1723   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1724                 :            : 
    1725                 :          0 :         return s->pending;
    1726                 :            : }
    1727                 :            : 
    1728                 :          0 : _public_ int sd_event_source_get_io_fd(sd_event_source *s) {
    1729   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    1730   [ #  #  #  # ]:          0 :         assert_return(s->type == SOURCE_IO, -EDOM);
    1731   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1732                 :            : 
    1733                 :          0 :         return s->io.fd;
    1734                 :            : }
    1735                 :            : 
    1736                 :         24 : _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) {
    1737                 :            :         int r;
    1738                 :            : 
    1739   [ -  +  -  + ]:         24 :         assert_return(s, -EINVAL);
    1740   [ -  +  -  + ]:         24 :         assert_return(fd >= 0, -EBADF);
    1741   [ -  +  -  + ]:         24 :         assert_return(s->type == SOURCE_IO, -EDOM);
    1742   [ -  +  -  + ]:         24 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1743                 :            : 
    1744         [ +  - ]:         24 :         if (s->io.fd == fd)
    1745                 :         24 :                 return 0;
    1746                 :            : 
    1747         [ #  # ]:          0 :         if (s->enabled == SD_EVENT_OFF) {
    1748                 :          0 :                 s->io.fd = fd;
    1749                 :          0 :                 s->io.registered = false;
    1750                 :            :         } else {
    1751                 :            :                 int saved_fd;
    1752                 :            : 
    1753                 :          0 :                 saved_fd = s->io.fd;
    1754         [ #  # ]:          0 :                 assert(s->io.registered);
    1755                 :            : 
    1756                 :          0 :                 s->io.fd = fd;
    1757                 :          0 :                 s->io.registered = false;
    1758                 :            : 
    1759                 :          0 :                 r = source_io_register(s, s->enabled, s->io.events);
    1760         [ #  # ]:          0 :                 if (r < 0) {
    1761                 :          0 :                         s->io.fd = saved_fd;
    1762                 :          0 :                         s->io.registered = true;
    1763                 :          0 :                         return r;
    1764                 :            :                 }
    1765                 :            : 
    1766                 :          0 :                 epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, saved_fd, NULL);
    1767                 :            :         }
    1768                 :            : 
    1769                 :          0 :         return 0;
    1770                 :            : }
    1771                 :            : 
    1772                 :          0 : _public_ int sd_event_source_get_io_fd_own(sd_event_source *s) {
    1773   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    1774   [ #  #  #  # ]:          0 :         assert_return(s->type == SOURCE_IO, -EDOM);
    1775                 :            : 
    1776                 :          0 :         return s->io.owned;
    1777                 :            : }
    1778                 :            : 
    1779                 :          0 : _public_ int sd_event_source_set_io_fd_own(sd_event_source *s, int own) {
    1780   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    1781   [ #  #  #  # ]:          0 :         assert_return(s->type == SOURCE_IO, -EDOM);
    1782                 :            : 
    1783                 :          0 :         s->io.owned = own;
    1784                 :          0 :         return 0;
    1785                 :            : }
    1786                 :            : 
    1787                 :          0 : _public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) {
    1788   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    1789   [ #  #  #  # ]:          0 :         assert_return(events, -EINVAL);
    1790   [ #  #  #  # ]:          0 :         assert_return(s->type == SOURCE_IO, -EDOM);
    1791   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1792                 :            : 
    1793                 :          0 :         *events = s->io.events;
    1794                 :          0 :         return 0;
    1795                 :            : }
    1796                 :            : 
    1797                 :    1435826 : _public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) {
    1798                 :            :         int r;
    1799                 :            : 
    1800   [ -  +  -  + ]:    1435826 :         assert_return(s, -EINVAL);
    1801   [ -  +  -  + ]:    1435826 :         assert_return(s->type == SOURCE_IO, -EDOM);
    1802   [ -  +  -  + ]:    1435826 :         assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL);
    1803   [ -  +  -  + ]:    1435826 :         assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
    1804   [ -  +  -  + ]:    1435826 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1805                 :            : 
    1806                 :            :         /* edge-triggered updates are never skipped, so we can reset edges */
    1807   [ +  +  +  - ]:    1435826 :         if (s->io.events == events && !(events & EPOLLET))
    1808                 :    1431141 :                 return 0;
    1809                 :            : 
    1810                 :       4685 :         r = source_set_pending(s, false);
    1811         [ -  + ]:       4685 :         if (r < 0)
    1812                 :          0 :                 return r;
    1813                 :            : 
    1814         [ +  - ]:       4685 :         if (s->enabled != SD_EVENT_OFF) {
    1815                 :       4685 :                 r = source_io_register(s, s->enabled, events);
    1816         [ -  + ]:       4685 :                 if (r < 0)
    1817                 :          0 :                         return r;
    1818                 :            :         }
    1819                 :            : 
    1820                 :       4685 :         s->io.events = events;
    1821                 :            : 
    1822                 :       4685 :         return 0;
    1823                 :            : }
    1824                 :            : 
    1825                 :          0 : _public_ int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents) {
    1826   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    1827   [ #  #  #  # ]:          0 :         assert_return(revents, -EINVAL);
    1828   [ #  #  #  # ]:          0 :         assert_return(s->type == SOURCE_IO, -EDOM);
    1829   [ #  #  #  # ]:          0 :         assert_return(s->pending, -ENODATA);
    1830   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1831                 :            : 
    1832                 :          0 :         *revents = s->io.revents;
    1833                 :          0 :         return 0;
    1834                 :            : }
    1835                 :            : 
    1836                 :          0 : _public_ int sd_event_source_get_signal(sd_event_source *s) {
    1837   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    1838   [ #  #  #  # ]:          0 :         assert_return(s->type == SOURCE_SIGNAL, -EDOM);
    1839   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1840                 :            : 
    1841                 :          0 :         return s->signal.sig;
    1842                 :            : }
    1843                 :            : 
    1844                 :          4 : _public_ int sd_event_source_get_priority(sd_event_source *s, int64_t *priority) {
    1845   [ -  +  -  + ]:          4 :         assert_return(s, -EINVAL);
    1846   [ -  +  -  + ]:          4 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1847                 :            : 
    1848                 :          4 :         *priority = s->priority;
    1849                 :          4 :         return 0;
    1850                 :            : }
    1851                 :            : 
    1852                 :       8392 : _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) {
    1853                 :       8392 :         bool rm_inotify = false, rm_inode = false;
    1854                 :       8392 :         struct inotify_data *new_inotify_data = NULL;
    1855                 :       8392 :         struct inode_data *new_inode_data = NULL;
    1856                 :            :         int r;
    1857                 :            : 
    1858   [ -  +  -  + ]:       8392 :         assert_return(s, -EINVAL);
    1859   [ -  +  -  + ]:       8392 :         assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
    1860   [ -  +  -  + ]:       8392 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1861                 :            : 
    1862         [ +  + ]:       8392 :         if (s->priority == priority)
    1863                 :       2600 :                 return 0;
    1864                 :            : 
    1865         [ +  + ]:       5792 :         if (s->type == SOURCE_INOTIFY) {
    1866                 :            :                 struct inode_data *old_inode_data;
    1867                 :            : 
    1868         [ -  + ]:         24 :                 assert(s->inotify.inode_data);
    1869                 :         24 :                 old_inode_data = s->inotify.inode_data;
    1870                 :            : 
    1871                 :            :                 /* We need the original fd to change the priority. If we don't have it we can't change the priority,
    1872                 :            :                  * anymore. Note that we close any fds when entering the next event loop iteration, i.e. for inotify
    1873                 :            :                  * events we allow priority changes only until the first following iteration. */
    1874         [ -  + ]:         24 :                 if (old_inode_data->fd < 0)
    1875                 :          0 :                         return -EOPNOTSUPP;
    1876                 :            : 
    1877                 :         24 :                 r = event_make_inotify_data(s->event, priority, &new_inotify_data);
    1878         [ -  + ]:         24 :                 if (r < 0)
    1879                 :          0 :                         return r;
    1880                 :         24 :                 rm_inotify = r > 0;
    1881                 :            : 
    1882                 :         24 :                 r = event_make_inode_data(s->event, new_inotify_data, old_inode_data->dev, old_inode_data->ino, &new_inode_data);
    1883         [ -  + ]:         24 :                 if (r < 0)
    1884                 :          0 :                         goto fail;
    1885                 :         24 :                 rm_inode = r > 0;
    1886                 :            : 
    1887         [ +  + ]:         24 :                 if (new_inode_data->fd < 0) {
    1888                 :            :                         /* Duplicate the fd for the new inode object if we don't have any yet */
    1889                 :         16 :                         new_inode_data->fd = fcntl(old_inode_data->fd, F_DUPFD_CLOEXEC, 3);
    1890         [ -  + ]:         16 :                         if (new_inode_data->fd < 0) {
    1891                 :          0 :                                 r = -errno;
    1892                 :          0 :                                 goto fail;
    1893                 :            :                         }
    1894                 :            : 
    1895   [ -  +  +  - ]:         16 :                         LIST_PREPEND(to_close, s->event->inode_data_to_close, new_inode_data);
    1896                 :            :                 }
    1897                 :            : 
    1898                 :            :                 /* Move the event source to the new inode data structure */
    1899   [ -  +  +  +  :         24 :                 LIST_REMOVE(inotify.by_inode_data, old_inode_data->event_sources, s);
             -  +  -  + ]
    1900   [ -  +  +  + ]:         24 :                 LIST_PREPEND(inotify.by_inode_data, new_inode_data->event_sources, s);
    1901                 :         24 :                 s->inotify.inode_data = new_inode_data;
    1902                 :            : 
    1903                 :            :                 /* Now create the new watch */
    1904                 :         24 :                 r = inode_data_realize_watch(s->event, new_inode_data);
    1905         [ -  + ]:         24 :                 if (r < 0) {
    1906                 :            :                         /* Move it back */
    1907   [ #  #  #  #  :          0 :                         LIST_REMOVE(inotify.by_inode_data, new_inode_data->event_sources, s);
             #  #  #  # ]
    1908   [ #  #  #  # ]:          0 :                         LIST_PREPEND(inotify.by_inode_data, old_inode_data->event_sources, s);
    1909                 :          0 :                         s->inotify.inode_data = old_inode_data;
    1910                 :          0 :                         goto fail;
    1911                 :            :                 }
    1912                 :            : 
    1913                 :         24 :                 s->priority = priority;
    1914                 :            : 
    1915                 :         24 :                 event_gc_inode_data(s->event, old_inode_data);
    1916                 :            : 
    1917   [ +  +  +  - ]:       5772 :         } else if (s->type == SOURCE_SIGNAL && s->enabled != SD_EVENT_OFF) {
    1918                 :            :                 struct signal_data *old, *d;
    1919                 :            : 
    1920                 :            :                 /* Move us from the signalfd belonging to the old
    1921                 :            :                  * priority to the signalfd of the new priority */
    1922                 :            : 
    1923         [ -  + ]:          4 :                 assert_se(old = hashmap_get(s->event->signal_data, &s->priority));
    1924                 :            : 
    1925                 :          4 :                 s->priority = priority;
    1926                 :            : 
    1927                 :          4 :                 r = event_make_signal_data(s->event, s->signal.sig, &d);
    1928         [ -  + ]:          4 :                 if (r < 0) {
    1929                 :          0 :                         s->priority = old->priority;
    1930                 :          0 :                         return r;
    1931                 :            :                 }
    1932                 :            : 
    1933                 :          4 :                 event_unmask_signal_data(s->event, old, s->signal.sig);
    1934                 :            :         } else
    1935                 :       5764 :                 s->priority = priority;
    1936                 :            : 
    1937         [ +  + ]:       5792 :         if (s->pending)
    1938                 :       1528 :                 prioq_reshuffle(s->event->pending, s, &s->pending_index);
    1939                 :            : 
    1940         [ +  + ]:       5792 :         if (s->prepare)
    1941                 :       1332 :                 prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
    1942                 :            : 
    1943         [ +  + ]:       5792 :         if (s->type == SOURCE_EXIT)
    1944                 :       1332 :                 prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
    1945                 :            : 
    1946                 :       5792 :         return 0;
    1947                 :            : 
    1948                 :          0 : fail:
    1949         [ #  # ]:          0 :         if (rm_inode)
    1950                 :          0 :                 event_free_inode_data(s->event, new_inode_data);
    1951                 :            : 
    1952         [ #  # ]:          0 :         if (rm_inotify)
    1953                 :          0 :                 event_free_inotify_data(s->event, new_inotify_data);
    1954                 :            : 
    1955                 :          0 :         return r;
    1956                 :            : }
    1957                 :            : 
    1958                 :          0 : _public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) {
    1959   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    1960   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1961                 :            : 
    1962         [ #  # ]:          0 :         if (m)
    1963                 :          0 :                 *m = s->enabled;
    1964                 :          0 :         return s->enabled != SD_EVENT_OFF;
    1965                 :            : }
    1966                 :            : 
    1967                 :    1453129 : _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
    1968                 :            :         int r;
    1969                 :            : 
    1970   [ -  +  -  + ]:    1453129 :         assert_return(s, -EINVAL);
    1971   [ +  -  -  +  :    1453129 :         assert_return(IN_SET(m, SD_EVENT_OFF, SD_EVENT_ON, SD_EVENT_ONESHOT), -EINVAL);
                   -  + ]
    1972   [ -  +  -  + ]:    1453129 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    1973                 :            : 
    1974                 :            :         /* If we are dead anyway, we are fine with turning off
    1975                 :            :          * sources, but everything else needs to fail. */
    1976         [ +  + ]:    1453129 :         if (s->event->state == SD_EVENT_FINISHED)
    1977         [ +  - ]:          8 :                 return m == SD_EVENT_OFF ? 0 : -ESTALE;
    1978                 :            : 
    1979         [ +  + ]:    1453121 :         if (s->enabled == m)
    1980                 :    1440461 :                 return 0;
    1981                 :            : 
    1982         [ +  + ]:      12660 :         if (m == SD_EVENT_OFF) {
    1983                 :            : 
    1984                 :            :                 /* Unset the pending flag when this event source is disabled */
    1985   [ +  +  +  + ]:      10260 :                 if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
    1986                 :       4108 :                         r = source_set_pending(s, false);
    1987         [ -  + ]:       4108 :                         if (r < 0)
    1988                 :          0 :                                 return r;
    1989                 :            :                 }
    1990                 :            : 
    1991   [ +  +  +  +  :      10260 :                 switch (s->type) {
                +  +  - ]
    1992                 :            : 
    1993                 :       1972 :                 case SOURCE_IO:
    1994                 :       1972 :                         source_io_unregister(s);
    1995                 :       1972 :                         s->enabled = m;
    1996                 :       1972 :                         break;
    1997                 :            : 
    1998                 :       2128 :                 case SOURCE_TIME_REALTIME:
    1999                 :            :                 case SOURCE_TIME_BOOTTIME:
    2000                 :            :                 case SOURCE_TIME_MONOTONIC:
    2001                 :            :                 case SOURCE_TIME_REALTIME_ALARM:
    2002                 :            :                 case SOURCE_TIME_BOOTTIME_ALARM: {
    2003                 :            :                         struct clock_data *d;
    2004                 :            : 
    2005                 :       2128 :                         s->enabled = m;
    2006                 :       2128 :                         d = event_get_clock_data(s->event, s->type);
    2007         [ -  + ]:       2128 :                         assert(d);
    2008                 :            : 
    2009                 :       2128 :                         prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
    2010                 :       2128 :                         prioq_reshuffle(d->latest, s, &s->time.latest_index);
    2011                 :       2128 :                         d->needs_rearm = true;
    2012                 :       2128 :                         break;
    2013                 :            :                 }
    2014                 :            : 
    2015                 :          4 :                 case SOURCE_SIGNAL:
    2016                 :          4 :                         s->enabled = m;
    2017                 :            : 
    2018                 :          4 :                         event_gc_signal_data(s->event, &s->priority, s->signal.sig);
    2019                 :          4 :                         break;
    2020                 :            : 
    2021                 :          4 :                 case SOURCE_CHILD:
    2022                 :          4 :                         s->enabled = m;
    2023                 :            : 
    2024         [ -  + ]:          4 :                         assert(s->event->n_enabled_child_sources > 0);
    2025                 :          4 :                         s->event->n_enabled_child_sources--;
    2026                 :            : 
    2027                 :          4 :                         event_gc_signal_data(s->event, &s->priority, SIGCHLD);
    2028                 :          4 :                         break;
    2029                 :            : 
    2030                 :       1944 :                 case SOURCE_EXIT:
    2031                 :       1944 :                         s->enabled = m;
    2032                 :       1944 :                         prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
    2033                 :       1944 :                         break;
    2034                 :            : 
    2035                 :       4208 :                 case SOURCE_DEFER:
    2036                 :            :                 case SOURCE_POST:
    2037                 :            :                 case SOURCE_INOTIFY:
    2038                 :       4208 :                         s->enabled = m;
    2039                 :       4208 :                         break;
    2040                 :            : 
    2041                 :          0 :                 default:
    2042                 :          0 :                         assert_not_reached("Wut? I shouldn't exist.");
    2043                 :            :                 }
    2044                 :            : 
    2045                 :            :         } else {
    2046                 :            : 
    2047                 :            :                 /* Unset the pending flag when this event source is enabled */
    2048   [ +  +  +  +  :       2400 :                 if (s->enabled == SD_EVENT_OFF && !IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
                   +  + ]
    2049                 :        156 :                         r = source_set_pending(s, false);
    2050         [ -  + ]:        156 :                         if (r < 0)
    2051                 :          0 :                                 return r;
    2052                 :            :                 }
    2053                 :            : 
    2054   [ +  +  +  -  :       2400 :                 switch (s->type) {
                -  +  - ]
    2055                 :            : 
    2056                 :         12 :                 case SOURCE_IO:
    2057                 :         12 :                         r = source_io_register(s, m, s->io.events);
    2058         [ -  + ]:         12 :                         if (r < 0)
    2059                 :          0 :                                 return r;
    2060                 :            : 
    2061                 :         12 :                         s->enabled = m;
    2062                 :         12 :                         break;
    2063                 :            : 
    2064                 :        196 :                 case SOURCE_TIME_REALTIME:
    2065                 :            :                 case SOURCE_TIME_BOOTTIME:
    2066                 :            :                 case SOURCE_TIME_MONOTONIC:
    2067                 :            :                 case SOURCE_TIME_REALTIME_ALARM:
    2068                 :            :                 case SOURCE_TIME_BOOTTIME_ALARM: {
    2069                 :            :                         struct clock_data *d;
    2070                 :            : 
    2071                 :        196 :                         s->enabled = m;
    2072                 :        196 :                         d = event_get_clock_data(s->event, s->type);
    2073         [ -  + ]:        196 :                         assert(d);
    2074                 :            : 
    2075                 :        196 :                         prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
    2076                 :        196 :                         prioq_reshuffle(d->latest, s, &s->time.latest_index);
    2077                 :        196 :                         d->needs_rearm = true;
    2078                 :        196 :                         break;
    2079                 :            :                 }
    2080                 :            : 
    2081                 :          4 :                 case SOURCE_SIGNAL:
    2082                 :            : 
    2083                 :          4 :                         s->enabled = m;
    2084                 :            : 
    2085                 :          4 :                         r = event_make_signal_data(s->event, s->signal.sig, NULL);
    2086         [ -  + ]:          4 :                         if (r < 0) {
    2087                 :          0 :                                 s->enabled = SD_EVENT_OFF;
    2088                 :          0 :                                 event_gc_signal_data(s->event, &s->priority, s->signal.sig);
    2089                 :          0 :                                 return r;
    2090                 :            :                         }
    2091                 :            : 
    2092                 :          4 :                         break;
    2093                 :            : 
    2094                 :          0 :                 case SOURCE_CHILD:
    2095                 :            : 
    2096         [ #  # ]:          0 :                         if (s->enabled == SD_EVENT_OFF)
    2097                 :          0 :                                 s->event->n_enabled_child_sources++;
    2098                 :            : 
    2099                 :          0 :                         s->enabled = m;
    2100                 :            : 
    2101                 :          0 :                         r = event_make_signal_data(s->event, SIGCHLD, NULL);
    2102         [ #  # ]:          0 :                         if (r < 0) {
    2103                 :          0 :                                 s->enabled = SD_EVENT_OFF;
    2104                 :          0 :                                 s->event->n_enabled_child_sources--;
    2105                 :          0 :                                 event_gc_signal_data(s->event, &s->priority, SIGCHLD);
    2106                 :          0 :                                 return r;
    2107                 :            :                         }
    2108                 :            : 
    2109                 :          0 :                         break;
    2110                 :            : 
    2111                 :          0 :                 case SOURCE_EXIT:
    2112                 :          0 :                         s->enabled = m;
    2113                 :          0 :                         prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
    2114                 :          0 :                         break;
    2115                 :            : 
    2116                 :       2188 :                 case SOURCE_DEFER:
    2117                 :            :                 case SOURCE_POST:
    2118                 :            :                 case SOURCE_INOTIFY:
    2119                 :       2188 :                         s->enabled = m;
    2120                 :       2188 :                         break;
    2121                 :            : 
    2122                 :          0 :                 default:
    2123                 :          0 :                         assert_not_reached("Wut? I shouldn't exist.");
    2124                 :            :                 }
    2125                 :            :         }
    2126                 :            : 
    2127         [ +  + ]:      12660 :         if (s->pending)
    2128                 :       6396 :                 prioq_reshuffle(s->event->pending, s, &s->pending_index);
    2129                 :            : 
    2130         [ +  + ]:      12660 :         if (s->prepare)
    2131                 :       1956 :                 prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
    2132                 :            : 
    2133                 :      12660 :         return 0;
    2134                 :            : }
    2135                 :            : 
    2136                 :          0 : _public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
    2137   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    2138   [ #  #  #  # ]:          0 :         assert_return(usec, -EINVAL);
    2139   [ #  #  #  #  :          0 :         assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
                   #  # ]
    2140   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    2141                 :            : 
    2142                 :          0 :         *usec = s->time.next;
    2143                 :          0 :         return 0;
    2144                 :            : }
    2145                 :            : 
    2146                 :       4806 : _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
    2147                 :            :         struct clock_data *d;
    2148                 :            :         int r;
    2149                 :            : 
    2150   [ -  +  -  + ]:       4806 :         assert_return(s, -EINVAL);
    2151   [ +  -  -  +  :       4806 :         assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
                   -  + ]
    2152   [ -  +  -  + ]:       4806 :         assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
    2153   [ -  +  -  + ]:       4806 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    2154                 :            : 
    2155                 :       4806 :         r = source_set_pending(s, false);
    2156         [ -  + ]:       4806 :         if (r < 0)
    2157                 :          0 :                 return r;
    2158                 :            : 
    2159                 :       4806 :         s->time.next = usec;
    2160                 :            : 
    2161                 :       4806 :         d = event_get_clock_data(s->event, s->type);
    2162         [ -  + ]:       4806 :         assert(d);
    2163                 :            : 
    2164                 :       4806 :         prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
    2165                 :       4806 :         prioq_reshuffle(d->latest, s, &s->time.latest_index);
    2166                 :       4806 :         d->needs_rearm = true;
    2167                 :            : 
    2168                 :       4806 :         return 0;
    2169                 :            : }
    2170                 :            : 
    2171                 :          0 : _public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) {
    2172   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    2173   [ #  #  #  # ]:          0 :         assert_return(usec, -EINVAL);
    2174   [ #  #  #  #  :          0 :         assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
                   #  # ]
    2175   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    2176                 :            : 
    2177                 :          0 :         *usec = s->time.accuracy;
    2178                 :          0 :         return 0;
    2179                 :            : }
    2180                 :            : 
    2181                 :        172 : _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) {
    2182                 :            :         struct clock_data *d;
    2183                 :            :         int r;
    2184                 :            : 
    2185   [ -  +  -  + ]:        172 :         assert_return(s, -EINVAL);
    2186   [ -  +  -  + ]:        172 :         assert_return(usec != (uint64_t) -1, -EINVAL);
    2187   [ +  -  -  +  :        172 :         assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
                   -  + ]
    2188   [ -  +  -  + ]:        172 :         assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
    2189   [ -  +  -  + ]:        172 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    2190                 :            : 
    2191                 :        172 :         r = source_set_pending(s, false);
    2192         [ -  + ]:        172 :         if (r < 0)
    2193                 :          0 :                 return r;
    2194                 :            : 
    2195         [ +  + ]:        172 :         if (usec == 0)
    2196                 :         60 :                 usec = DEFAULT_ACCURACY_USEC;
    2197                 :            : 
    2198                 :        172 :         s->time.accuracy = usec;
    2199                 :            : 
    2200                 :        172 :         d = event_get_clock_data(s->event, s->type);
    2201         [ -  + ]:        172 :         assert(d);
    2202                 :            : 
    2203                 :        172 :         prioq_reshuffle(d->latest, s, &s->time.latest_index);
    2204                 :        172 :         d->needs_rearm = true;
    2205                 :            : 
    2206                 :        172 :         return 0;
    2207                 :            : }
    2208                 :            : 
    2209                 :        172 : _public_ int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock) {
    2210   [ -  +  -  + ]:        172 :         assert_return(s, -EINVAL);
    2211   [ -  +  -  + ]:        172 :         assert_return(clock, -EINVAL);
    2212   [ +  -  -  +  :        172 :         assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
                   -  + ]
    2213   [ -  +  -  + ]:        172 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    2214                 :            : 
    2215                 :        172 :         *clock = event_source_type_to_clock(s->type);
    2216                 :        172 :         return 0;
    2217                 :            : }
    2218                 :            : 
    2219                 :          0 : _public_ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) {
    2220   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    2221   [ #  #  #  # ]:          0 :         assert_return(pid, -EINVAL);
    2222   [ #  #  #  # ]:          0 :         assert_return(s->type == SOURCE_CHILD, -EDOM);
    2223   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    2224                 :            : 
    2225                 :          0 :         *pid = s->child.pid;
    2226                 :          0 :         return 0;
    2227                 :            : }
    2228                 :            : 
    2229                 :          0 : _public_ int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *mask) {
    2230   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    2231   [ #  #  #  # ]:          0 :         assert_return(mask, -EINVAL);
    2232   [ #  #  #  # ]:          0 :         assert_return(s->type == SOURCE_INOTIFY, -EDOM);
    2233   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    2234                 :            : 
    2235                 :          0 :         *mask = s->inotify.mask;
    2236                 :          0 :         return 0;
    2237                 :            : }
    2238                 :            : 
    2239                 :       1960 : _public_ int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback) {
    2240                 :            :         int r;
    2241                 :            : 
    2242   [ -  +  -  + ]:       1960 :         assert_return(s, -EINVAL);
    2243   [ -  +  -  + ]:       1960 :         assert_return(s->type != SOURCE_EXIT, -EDOM);
    2244   [ -  +  -  + ]:       1960 :         assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
    2245   [ -  +  -  + ]:       1960 :         assert_return(!event_pid_changed(s->event), -ECHILD);
    2246                 :            : 
    2247         [ -  + ]:       1960 :         if (s->prepare == callback)
    2248                 :          0 :                 return 0;
    2249                 :            : 
    2250   [ +  -  -  + ]:       1960 :         if (callback && s->prepare) {
    2251                 :          0 :                 s->prepare = callback;
    2252                 :          0 :                 return 0;
    2253                 :            :         }
    2254                 :            : 
    2255                 :       1960 :         r = prioq_ensure_allocated(&s->event->prepare, prepare_prioq_compare);
    2256         [ -  + ]:       1960 :         if (r < 0)
    2257                 :          0 :                 return r;
    2258                 :            : 
    2259                 :       1960 :         s->prepare = callback;
    2260                 :            : 
    2261         [ +  - ]:       1960 :         if (callback) {
    2262                 :       1960 :                 r = prioq_put(s->event->prepare, s, &s->prepare_index);
    2263         [ -  + ]:       1960 :                 if (r < 0)
    2264                 :          0 :                         return r;
    2265                 :            :         } else
    2266                 :          0 :                 prioq_remove(s->event->prepare, s, &s->prepare_index);
    2267                 :            : 
    2268                 :       1960 :         return 0;
    2269                 :            : }
    2270                 :            : 
    2271                 :          0 : _public_ void* sd_event_source_get_userdata(sd_event_source *s) {
    2272   [ #  #  #  # ]:          0 :         assert_return(s, NULL);
    2273                 :            : 
    2274                 :          0 :         return s->userdata;
    2275                 :            : }
    2276                 :            : 
    2277                 :        172 : _public_ void *sd_event_source_set_userdata(sd_event_source *s, void *userdata) {
    2278                 :            :         void *ret;
    2279                 :            : 
    2280   [ -  +  -  + ]:        172 :         assert_return(s, NULL);
    2281                 :            : 
    2282                 :        172 :         ret = s->userdata;
    2283                 :        172 :         s->userdata = userdata;
    2284                 :            : 
    2285                 :        172 :         return ret;
    2286                 :            : }
    2287                 :            : 
    2288                 :        378 : static usec_t sleep_between(sd_event *e, usec_t a, usec_t b) {
    2289                 :            :         usec_t c;
    2290         [ -  + ]:        378 :         assert(e);
    2291         [ -  + ]:        378 :         assert(a <= b);
    2292                 :            : 
    2293         [ +  + ]:        378 :         if (a <= 0)
    2294                 :        140 :                 return 0;
    2295         [ -  + ]:        238 :         if (a >= USEC_INFINITY)
    2296                 :          0 :                 return USEC_INFINITY;
    2297                 :            : 
    2298         [ -  + ]:        238 :         if (b <= a + 1)
    2299                 :          0 :                 return a;
    2300                 :            : 
    2301                 :        238 :         initialize_perturb(e);
    2302                 :            : 
    2303                 :            :         /*
    2304                 :            :           Find a good time to wake up again between times a and b. We
    2305                 :            :           have two goals here:
    2306                 :            : 
    2307                 :            :           a) We want to wake up as seldom as possible, hence prefer
    2308                 :            :              later times over earlier times.
    2309                 :            : 
    2310                 :            :           b) But if we have to wake up, then let's make sure to
    2311                 :            :              dispatch as much as possible on the entire system.
    2312                 :            : 
    2313                 :            :           We implement this by waking up everywhere at the same time
    2314                 :            :           within any given minute if we can, synchronised via the
    2315                 :            :           perturbation value determined from the boot ID. If we can't,
    2316                 :            :           then we try to find the same spot in every 10s, then 1s and
    2317                 :            :           then 250ms step. Otherwise, we pick the last possible time
    2318                 :            :           to wake up.
    2319                 :            :         */
    2320                 :            : 
    2321                 :        238 :         c = (b / USEC_PER_MINUTE) * USEC_PER_MINUTE + e->perturb;
    2322         [ +  + ]:        238 :         if (c >= b) {
    2323         [ -  + ]:        230 :                 if (_unlikely_(c < USEC_PER_MINUTE))
    2324                 :          0 :                         return b;
    2325                 :            : 
    2326                 :        230 :                 c -= USEC_PER_MINUTE;
    2327                 :            :         }
    2328                 :            : 
    2329         [ +  + ]:        238 :         if (c >= a)
    2330                 :          2 :                 return c;
    2331                 :            : 
    2332                 :        236 :         c = (b / (USEC_PER_SEC*10)) * (USEC_PER_SEC*10) + (e->perturb % (USEC_PER_SEC*10));
    2333         [ +  + ]:        236 :         if (c >= b) {
    2334         [ -  + ]:        216 :                 if (_unlikely_(c < USEC_PER_SEC*10))
    2335                 :          0 :                         return b;
    2336                 :            : 
    2337                 :        216 :                 c -= USEC_PER_SEC*10;
    2338                 :            :         }
    2339                 :            : 
    2340         [ +  + ]:        236 :         if (c >= a)
    2341                 :          6 :                 return c;
    2342                 :            : 
    2343                 :        230 :         c = (b / USEC_PER_SEC) * USEC_PER_SEC + (e->perturb % USEC_PER_SEC);
    2344         [ +  + ]:        230 :         if (c >= b) {
    2345         [ -  + ]:         74 :                 if (_unlikely_(c < USEC_PER_SEC))
    2346                 :          0 :                         return b;
    2347                 :            : 
    2348                 :         74 :                 c -= USEC_PER_SEC;
    2349                 :            :         }
    2350                 :            : 
    2351         [ +  + ]:        230 :         if (c >= a)
    2352                 :         33 :                 return c;
    2353                 :            : 
    2354                 :        197 :         c = (b / (USEC_PER_MSEC*250)) * (USEC_PER_MSEC*250) + (e->perturb % (USEC_PER_MSEC*250));
    2355         [ +  + ]:        197 :         if (c >= b) {
    2356         [ -  + ]:         58 :                 if (_unlikely_(c < USEC_PER_MSEC*250))
    2357                 :          0 :                         return b;
    2358                 :            : 
    2359                 :         58 :                 c -= USEC_PER_MSEC*250;
    2360                 :            :         }
    2361                 :            : 
    2362         [ +  + ]:        197 :         if (c >= a)
    2363                 :        185 :                 return c;
    2364                 :            : 
    2365                 :         12 :         return b;
    2366                 :            : }
    2367                 :            : 
    2368                 :    1031170 : static int event_arm_timer(
    2369                 :            :                 sd_event *e,
    2370                 :            :                 struct clock_data *d) {
    2371                 :            : 
    2372                 :    1031170 :         struct itimerspec its = {};
    2373                 :            :         sd_event_source *a, *b;
    2374                 :            :         usec_t t;
    2375                 :            :         int r;
    2376                 :            : 
    2377         [ -  + ]:    1031170 :         assert(e);
    2378         [ -  + ]:    1031170 :         assert(d);
    2379                 :            : 
    2380         [ +  + ]:    1031170 :         if (!d->needs_rearm)
    2381                 :    1025588 :                 return 0;
    2382                 :            :         else
    2383                 :       5582 :                 d->needs_rearm = false;
    2384                 :            : 
    2385                 :       5582 :         a = prioq_peek(d->earliest);
    2386   [ +  +  +  +  :       5582 :         if (!a || a->enabled == SD_EVENT_OFF || a->time.next == USEC_INFINITY) {
                   -  + ]
    2387                 :            : 
    2388         [ -  + ]:       5204 :                 if (d->fd < 0)
    2389                 :          0 :                         return 0;
    2390                 :            : 
    2391         [ +  + ]:       5204 :                 if (d->next == USEC_INFINITY)
    2392                 :       5181 :                         return 0;
    2393                 :            : 
    2394                 :            :                 /* disarm */
    2395                 :         23 :                 r = timerfd_settime(d->fd, TFD_TIMER_ABSTIME, &its, NULL);
    2396         [ -  + ]:         23 :                 if (r < 0)
    2397                 :          0 :                         return r;
    2398                 :            : 
    2399                 :         23 :                 d->next = USEC_INFINITY;
    2400                 :         23 :                 return 0;
    2401                 :            :         }
    2402                 :            : 
    2403                 :        378 :         b = prioq_peek(d->latest);
    2404   [ +  -  -  + ]:        378 :         assert_se(b && b->enabled != SD_EVENT_OFF);
    2405                 :            : 
    2406                 :        378 :         t = sleep_between(e, a->time.next, time_event_source_latest(b));
    2407         [ +  + ]:        378 :         if (d->next == t)
    2408                 :        126 :                 return 0;
    2409                 :            : 
    2410         [ -  + ]:        252 :         assert_se(d->fd >= 0);
    2411                 :            : 
    2412         [ +  + ]:        252 :         if (t == 0) {
    2413                 :            :                 /* We don' want to disarm here, just mean some time looooong ago. */
    2414                 :        140 :                 its.it_value.tv_sec = 0;
    2415                 :        140 :                 its.it_value.tv_nsec = 1;
    2416                 :            :         } else
    2417                 :        112 :                 timespec_store(&its.it_value, t);
    2418                 :            : 
    2419                 :        252 :         r = timerfd_settime(d->fd, TFD_TIMER_ABSTIME, &its, NULL);
    2420         [ -  + ]:        252 :         if (r < 0)
    2421                 :          0 :                 return -errno;
    2422                 :            : 
    2423                 :        252 :         d->next = t;
    2424                 :        252 :         return 0;
    2425                 :            : }
    2426                 :            : 
    2427                 :     689996 : static int process_io(sd_event *e, sd_event_source *s, uint32_t revents) {
    2428         [ -  + ]:     689996 :         assert(e);
    2429         [ -  + ]:     689996 :         assert(s);
    2430         [ -  + ]:     689996 :         assert(s->type == SOURCE_IO);
    2431                 :            : 
    2432                 :            :         /* If the event source was already pending, we just OR in the
    2433                 :            :          * new revents, otherwise we reset the value. The ORing is
    2434                 :            :          * necessary to handle EPOLLONESHOT events properly where
    2435                 :            :          * readability might happen independently of writability, and
    2436                 :            :          * we need to keep track of both */
    2437                 :            : 
    2438         [ +  + ]:     689996 :         if (s->pending)
    2439                 :     685655 :                 s->io.revents |= revents;
    2440                 :            :         else
    2441                 :       4341 :                 s->io.revents = revents;
    2442                 :            : 
    2443                 :     689996 :         return source_set_pending(s, true);
    2444                 :            : }
    2445                 :            : 
    2446                 :        156 : static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) {
    2447                 :            :         uint64_t x;
    2448                 :            :         ssize_t ss;
    2449                 :            : 
    2450         [ -  + ]:        156 :         assert(e);
    2451         [ -  + ]:        156 :         assert(fd >= 0);
    2452                 :            : 
    2453   [ -  +  -  + ]:        156 :         assert_return(events == EPOLLIN, -EIO);
    2454                 :            : 
    2455                 :        156 :         ss = read(fd, &x, sizeof(x));
    2456         [ -  + ]:        156 :         if (ss < 0) {
    2457   [ #  #  #  # ]:          0 :                 if (IN_SET(errno, EAGAIN, EINTR))
    2458                 :          0 :                         return 0;
    2459                 :            : 
    2460                 :          0 :                 return -errno;
    2461                 :            :         }
    2462                 :            : 
    2463         [ -  + ]:        156 :         if (_unlikely_(ss != sizeof(x)))
    2464                 :          0 :                 return -EIO;
    2465                 :            : 
    2466         [ +  - ]:        156 :         if (next)
    2467                 :        156 :                 *next = USEC_INFINITY;
    2468                 :            : 
    2469                 :        156 :         return 0;
    2470                 :            : }
    2471                 :            : 
    2472                 :    1031170 : static int process_timer(
    2473                 :            :                 sd_event *e,
    2474                 :            :                 usec_t n,
    2475                 :            :                 struct clock_data *d) {
    2476                 :            : 
    2477                 :            :         sd_event_source *s;
    2478                 :            :         int r;
    2479                 :            : 
    2480         [ -  + ]:    1031170 :         assert(e);
    2481         [ -  + ]:    1031170 :         assert(d);
    2482                 :            : 
    2483                 :            :         for (;;) {
    2484                 :    1031322 :                 s = prioq_peek(d->earliest);
    2485         [ +  + ]:    1031322 :                 if (!s ||
    2486         [ +  + ]:       8486 :                     s->time.next > n ||
    2487   [ +  +  +  + ]:       8095 :                     s->enabled == SD_EVENT_OFF ||
    2488                 :            :                     s->pending)
    2489                 :            :                         break;
    2490                 :            : 
    2491                 :        152 :                 r = source_set_pending(s, true);
    2492         [ -  + ]:        152 :                 if (r < 0)
    2493                 :          0 :                         return r;
    2494                 :            : 
    2495                 :        152 :                 prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
    2496                 :        152 :                 prioq_reshuffle(d->latest, s, &s->time.latest_index);
    2497                 :        152 :                 d->needs_rearm = true;
    2498                 :            :         }
    2499                 :            : 
    2500                 :    1031170 :         return 0;
    2501                 :            : }
    2502                 :            : 
    2503                 :          8 : static int process_child(sd_event *e) {
    2504                 :            :         sd_event_source *s;
    2505                 :            :         Iterator i;
    2506                 :            :         int r;
    2507                 :            : 
    2508         [ -  + ]:          8 :         assert(e);
    2509                 :            : 
    2510                 :          8 :         e->need_process_child = false;
    2511                 :            : 
    2512                 :            :         /*
    2513                 :            :            So, this is ugly. We iteratively invoke waitid() with P_PID
    2514                 :            :            + WNOHANG for each PID we wait for, instead of using
    2515                 :            :            P_ALL. This is because we only want to get child
    2516                 :            :            information of very specific child processes, and not all
    2517                 :            :            of them. We might not have processed the SIGCHLD even of a
    2518                 :            :            previous invocation and we don't want to maintain a
    2519                 :            :            unbounded *per-child* event queue, hence we really don't
    2520                 :            :            want anything flushed out of the kernel's queue that we
    2521                 :            :            don't care about. Since this is O(n) this means that if you
    2522                 :            :            have a lot of processes you probably want to handle SIGCHLD
    2523                 :            :            yourself.
    2524                 :            : 
    2525                 :            :            We do not reap the children here (by using WNOWAIT), this
    2526                 :            :            is only done after the event source is dispatched so that
    2527                 :            :            the callback still sees the process as a zombie.
    2528                 :            :         */
    2529                 :            : 
    2530         [ +  + ]:         16 :         HASHMAP_FOREACH(s, e->child_sources, i) {
    2531         [ -  + ]:          8 :                 assert(s->type == SOURCE_CHILD);
    2532                 :            : 
    2533         [ -  + ]:          8 :                 if (s->pending)
    2534                 :          0 :                         continue;
    2535                 :            : 
    2536         [ -  + ]:          8 :                 if (s->enabled == SD_EVENT_OFF)
    2537                 :          0 :                         continue;
    2538                 :            : 
    2539         [ +  - ]:          8 :                 zero(s->child.siginfo);
    2540                 :          8 :                 r = waitid(P_PID, s->child.pid, &s->child.siginfo,
    2541                 :          8 :                            WNOHANG | (s->child.options & WEXITED ? WNOWAIT : 0) | s->child.options);
    2542         [ -  + ]:          8 :                 if (r < 0)
    2543                 :          0 :                         return -errno;
    2544                 :            : 
    2545         [ +  + ]:          8 :                 if (s->child.siginfo.si_pid != 0) {
    2546         [ +  - ]:          4 :                         bool zombie = IN_SET(s->child.siginfo.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED);
    2547                 :            : 
    2548   [ -  +  #  # ]:          4 :                         if (!zombie && (s->child.options & WEXITED)) {
    2549                 :            :                                 /* If the child isn't dead then let's
    2550                 :            :                                  * immediately remove the state change
    2551                 :            :                                  * from the queue, since there's no
    2552                 :            :                                  * benefit in leaving it queued */
    2553                 :            : 
    2554         [ #  # ]:          0 :                                 assert(s->child.options & (WSTOPPED|WCONTINUED));
    2555                 :          0 :                                 waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|(s->child.options & (WSTOPPED|WCONTINUED)));
    2556                 :            :                         }
    2557                 :            : 
    2558                 :          4 :                         r = source_set_pending(s, true);
    2559         [ -  + ]:          4 :                         if (r < 0)
    2560                 :          0 :                                 return r;
    2561                 :            :                 }
    2562                 :            :         }
    2563                 :            : 
    2564                 :          8 :         return 0;
    2565                 :            : }
    2566                 :            : 
    2567                 :         32 : static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
    2568                 :         32 :         bool read_one = false;
    2569                 :            :         int r;
    2570                 :            : 
    2571         [ -  + ]:         32 :         assert(e);
    2572         [ -  + ]:         32 :         assert(d);
    2573   [ -  +  -  + ]:         32 :         assert_return(events == EPOLLIN, -EIO);
    2574                 :            : 
    2575                 :            :         /* If there's a signal queued on this priority and SIGCHLD is
    2576                 :            :            on this priority too, then make sure to recheck the
    2577                 :            :            children we watch. This is because we only ever dequeue
    2578                 :            :            the first signal per priority, and if we dequeue one, and
    2579                 :            :            SIGCHLD might be enqueued later we wouldn't know, but we
    2580                 :            :            might have higher priority children we care about hence we
    2581                 :            :            need to check that explicitly. */
    2582                 :            : 
    2583         [ +  + ]:         32 :         if (sigismember(&d->sigset, SIGCHLD))
    2584                 :          4 :                 e->need_process_child = true;
    2585                 :            : 
    2586                 :            :         /* If there's already an event source pending for this
    2587                 :            :          * priority we don't read another */
    2588         [ +  + ]:         32 :         if (d->current)
    2589                 :          8 :                 return 0;
    2590                 :            : 
    2591                 :          4 :         for (;;) {
    2592                 :            :                 struct signalfd_siginfo si;
    2593                 :            :                 ssize_t n;
    2594                 :         28 :                 sd_event_source *s = NULL;
    2595                 :            : 
    2596                 :         28 :                 n = read(d->fd, &si, sizeof(si));
    2597         [ +  + ]:         28 :                 if (n < 0) {
    2598   [ +  -  +  - ]:          4 :                         if (IN_SET(errno, EAGAIN, EINTR))
    2599                 :         24 :                                 return read_one;
    2600                 :            : 
    2601                 :          0 :                         return -errno;
    2602                 :            :                 }
    2603                 :            : 
    2604         [ -  + ]:         24 :                 if (_unlikely_(n != sizeof(si)))
    2605                 :          0 :                         return -EIO;
    2606                 :            : 
    2607         [ -  + ]:         24 :                 assert(SIGNAL_VALID(si.ssi_signo));
    2608                 :            : 
    2609                 :         24 :                 read_one = true;
    2610                 :            : 
    2611         [ +  - ]:         24 :                 if (e->signal_sources)
    2612                 :         24 :                         s = e->signal_sources[si.ssi_signo];
    2613         [ +  + ]:         24 :                 if (!s)
    2614                 :          4 :                         continue;
    2615         [ -  + ]:         20 :                 if (s->pending)
    2616                 :          0 :                         continue;
    2617                 :            : 
    2618                 :         20 :                 s->signal.siginfo = si;
    2619                 :         20 :                 d->current = s;
    2620                 :            : 
    2621                 :         20 :                 r = source_set_pending(s, true);
    2622         [ -  + ]:         20 :                 if (r < 0)
    2623                 :          0 :                         return r;
    2624                 :            : 
    2625                 :         20 :                 return 1;
    2626                 :            :         }
    2627                 :            : }
    2628                 :            : 
    2629                 :     329584 : static int event_inotify_data_read(sd_event *e, struct inotify_data *d, uint32_t revents) {
    2630                 :            :         ssize_t n;
    2631                 :            : 
    2632         [ -  + ]:     329584 :         assert(e);
    2633         [ -  + ]:     329584 :         assert(d);
    2634                 :            : 
    2635   [ -  +  -  + ]:     329584 :         assert_return(revents == EPOLLIN, -EIO);
    2636                 :            : 
    2637                 :            :         /* If there's already an event source pending for this priority, don't read another */
    2638         [ +  + ]:     329584 :         if (d->n_pending > 0)
    2639                 :     197792 :                 return 0;
    2640                 :            : 
    2641                 :            :         /* Is the read buffer non-empty? If so, let's not read more */
    2642         [ +  + ]:     131792 :         if (d->buffer_filled > 0)
    2643                 :     115304 :                 return 0;
    2644                 :            : 
    2645                 :      16488 :         n = read(d->fd, &d->buffer, sizeof(d->buffer));
    2646         [ -  + ]:      16488 :         if (n < 0) {
    2647   [ #  #  #  # ]:          0 :                 if (IN_SET(errno, EAGAIN, EINTR))
    2648                 :          0 :                         return 0;
    2649                 :            : 
    2650                 :          0 :                 return -errno;
    2651                 :            :         }
    2652                 :            : 
    2653         [ -  + ]:      16488 :         assert(n > 0);
    2654                 :      16488 :         d->buffer_filled = (size_t) n;
    2655   [ -  +  +  + ]:      16488 :         LIST_PREPEND(buffered, e->inotify_data_buffered, d);
    2656                 :            : 
    2657                 :      16488 :         return 1;
    2658                 :            : }
    2659                 :            : 
    2660                 :     131900 : static void event_inotify_data_drop(sd_event *e, struct inotify_data *d, size_t sz) {
    2661         [ -  + ]:     131900 :         assert(e);
    2662         [ -  + ]:     131900 :         assert(d);
    2663         [ -  + ]:     131900 :         assert(sz <= d->buffer_filled);
    2664                 :            : 
    2665         [ -  + ]:     131900 :         if (sz == 0)
    2666                 :          0 :                 return;
    2667                 :            : 
    2668                 :            :         /* Move the rest to the buffer to the front, in order to get things properly aligned again */
    2669                 :     131900 :         memmove(d->buffer.raw, d->buffer.raw + sz, d->buffer_filled - sz);
    2670                 :     131900 :         d->buffer_filled -= sz;
    2671                 :            : 
    2672         [ +  + ]:     131900 :         if (d->buffer_filled == 0)
    2673   [ -  +  +  +  :      16484 :                 LIST_REMOVE(buffered, e->inotify_data_buffered, d);
             +  +  -  + ]
    2674                 :            : }
    2675                 :            : 
    2676                 :     329752 : static int event_inotify_data_process(sd_event *e, struct inotify_data *d) {
    2677                 :            :         int r;
    2678                 :            : 
    2679         [ -  + ]:     329752 :         assert(e);
    2680         [ -  + ]:     329752 :         assert(d);
    2681                 :            : 
    2682                 :            :         /* If there's already an event source pending for this priority, don't read another */
    2683         [ +  + ]:     329752 :         if (d->n_pending > 0)
    2684                 :     197852 :                 return 0;
    2685                 :            : 
    2686         [ +  - ]:     131900 :         while (d->buffer_filled > 0) {
    2687                 :            :                 size_t sz;
    2688                 :            : 
    2689                 :            :                 /* Let's validate that the event structures are complete */
    2690         [ -  + ]:     131900 :                 if (d->buffer_filled < offsetof(struct inotify_event, name))
    2691                 :          0 :                         return -EIO;
    2692                 :            : 
    2693                 :     131900 :                 sz = offsetof(struct inotify_event, name) + d->buffer.ev.len;
    2694         [ -  + ]:     131900 :                 if (d->buffer_filled < sz)
    2695                 :          0 :                         return -EIO;
    2696                 :            : 
    2697         [ +  + ]:     131900 :                 if (d->buffer.ev.mask & IN_Q_OVERFLOW) {
    2698                 :            :                         struct inode_data *inode_data;
    2699                 :            :                         Iterator i;
    2700                 :            : 
    2701                 :            :                         /* The queue overran, let's pass this event to all event sources connected to this inotify
    2702                 :            :                          * object */
    2703                 :            : 
    2704         [ +  + ]:         20 :                         HASHMAP_FOREACH(inode_data, d->inodes, i) {
    2705                 :            :                                 sd_event_source *s;
    2706                 :            : 
    2707         [ +  + ]:         28 :                                 LIST_FOREACH(inotify.by_inode_data, s, inode_data->event_sources) {
    2708                 :            : 
    2709         [ -  + ]:         16 :                                         if (s->enabled == SD_EVENT_OFF)
    2710                 :          0 :                                                 continue;
    2711                 :            : 
    2712                 :         16 :                                         r = source_set_pending(s, true);
    2713         [ -  + ]:         16 :                                         if (r < 0)
    2714                 :          0 :                                                 return r;
    2715                 :            :                                 }
    2716                 :            :                         }
    2717                 :            :                 } else {
    2718                 :            :                         struct inode_data *inode_data;
    2719                 :            :                         sd_event_source *s;
    2720                 :            : 
    2721                 :            :                         /* Find the inode object for this watch descriptor. If IN_IGNORED is set we also remove it from
    2722                 :            :                          * our watch descriptor table. */
    2723         [ +  + ]:     131892 :                         if (d->buffer.ev.mask & IN_IGNORED) {
    2724                 :            : 
    2725                 :          4 :                                 inode_data = hashmap_remove(d->wd, INT_TO_PTR(d->buffer.ev.wd));
    2726         [ -  + ]:          4 :                                 if (!inode_data) {
    2727                 :          0 :                                         event_inotify_data_drop(e, d, sz);
    2728                 :          0 :                                         continue;
    2729                 :            :                                 }
    2730                 :            : 
    2731                 :            :                                 /* The watch descriptor was removed by the kernel, let's drop it here too */
    2732                 :          4 :                                 inode_data->wd = -1;
    2733                 :            :                         } else {
    2734                 :     131888 :                                 inode_data = hashmap_get(d->wd, INT_TO_PTR(d->buffer.ev.wd));
    2735         [ -  + ]:     131888 :                                 if (!inode_data) {
    2736                 :          0 :                                         event_inotify_data_drop(e, d, sz);
    2737                 :          0 :                                         continue;
    2738                 :            :                                 }
    2739                 :            :                         }
    2740                 :            : 
    2741                 :            :                         /* Trigger all event sources that are interested in these events. Also trigger all event
    2742                 :            :                          * sources if IN_IGNORED or IN_UNMOUNT is set. */
    2743         [ +  + ]:     329728 :                         LIST_FOREACH(inotify.by_inode_data, s, inode_data->event_sources) {
    2744                 :            : 
    2745         [ -  + ]:     197836 :                                 if (s->enabled == SD_EVENT_OFF)
    2746                 :          0 :                                         continue;
    2747                 :            : 
    2748         [ +  + ]:     197836 :                                 if ((d->buffer.ev.mask & (IN_IGNORED|IN_UNMOUNT)) == 0 &&
    2749         [ +  + ]:     197832 :                                     (s->inotify.mask & d->buffer.ev.mask & IN_ALL_EVENTS) == 0)
    2750                 :          4 :                                         continue;
    2751                 :            : 
    2752                 :     197832 :                                 r = source_set_pending(s, true);
    2753         [ -  + ]:     197832 :                                 if (r < 0)
    2754                 :          0 :                                         return r;
    2755                 :            :                         }
    2756                 :            :                 }
    2757                 :            : 
    2758                 :            :                 /* Something pending now? If so, let's finish, otherwise let's read more. */
    2759         [ +  - ]:     131900 :                 if (d->n_pending > 0)
    2760                 :     131900 :                         return 1;
    2761                 :            :         }
    2762                 :            : 
    2763                 :          0 :         return 0;
    2764                 :            : }
    2765                 :            : 
    2766                 :     206234 : static int process_inotify(sd_event *e) {
    2767                 :            :         struct inotify_data *d;
    2768                 :     206234 :         int r, done = 0;
    2769                 :            : 
    2770         [ -  + ]:     206234 :         assert(e);
    2771                 :            : 
    2772         [ +  + ]:     535986 :         LIST_FOREACH(buffered, d, e->inotify_data_buffered) {
    2773                 :     329752 :                 r = event_inotify_data_process(e, d);
    2774         [ -  + ]:     329752 :                 if (r < 0)
    2775                 :          0 :                         return r;
    2776         [ +  + ]:     329752 :                 if (r > 0)
    2777                 :     131900 :                         done ++;
    2778                 :            :         }
    2779                 :            : 
    2780                 :     206234 :         return done;
    2781                 :            : }
    2782                 :            : 
    2783                 :     207013 : static int source_dispatch(sd_event_source *s) {
    2784                 :            :         EventSourceType saved_type;
    2785                 :     207013 :         int r = 0;
    2786                 :            : 
    2787         [ -  + ]:     207013 :         assert(s);
    2788   [ +  +  -  + ]:     207013 :         assert(s->pending || s->type == SOURCE_EXIT);
    2789                 :            : 
    2790                 :            :         /* Save the event source type, here, so that we still know it after the event callback which might invalidate
    2791                 :            :          * the event. */
    2792                 :     207013 :         saved_type = s->type;
    2793                 :            : 
    2794   [ +  +  +  + ]:     207013 :         if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
    2795                 :     200489 :                 r = source_set_pending(s, false);
    2796         [ -  + ]:     200489 :                 if (r < 0)
    2797                 :          0 :                         return r;
    2798                 :            :         }
    2799                 :            : 
    2800         [ +  + ]:     207013 :         if (s->type != SOURCE_POST) {
    2801                 :            :                 sd_event_source *z;
    2802                 :            :                 Iterator i;
    2803                 :            : 
    2804                 :            :                 /* If we execute a non-post source, let's mark all
    2805                 :            :                  * post sources as pending */
    2806                 :            : 
    2807         [ +  + ]:     207021 :                 SET_FOREACH(z, s->event->post_sources, i) {
    2808         [ -  + ]:         20 :                         if (z->enabled == SD_EVENT_OFF)
    2809                 :          0 :                                 continue;
    2810                 :            : 
    2811                 :         20 :                         r = source_set_pending(z, true);
    2812         [ -  + ]:         20 :                         if (r < 0)
    2813                 :          0 :                                 return r;
    2814                 :            :                 }
    2815                 :            :         }
    2816                 :            : 
    2817         [ +  + ]:     207013 :         if (s->enabled == SD_EVENT_ONESHOT) {
    2818                 :       2843 :                 r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
    2819         [ -  + ]:       2843 :                 if (r < 0)
    2820                 :          0 :                         return r;
    2821                 :            :         }
    2822                 :            : 
    2823                 :     207013 :         s->dispatching = true;
    2824                 :            : 
    2825   [ +  +  +  +  :     207013 :         switch (s->type) {
          +  +  +  +  -  
                      - ]
    2826                 :            : 
    2827                 :       2457 :         case SOURCE_IO:
    2828                 :       2457 :                 r = s->io.callback(s, s->io.fd, s->io.revents, s->userdata);
    2829                 :       2457 :                 break;
    2830                 :            : 
    2831                 :        148 :         case SOURCE_TIME_REALTIME:
    2832                 :            :         case SOURCE_TIME_BOOTTIME:
    2833                 :            :         case SOURCE_TIME_MONOTONIC:
    2834                 :            :         case SOURCE_TIME_REALTIME_ALARM:
    2835                 :            :         case SOURCE_TIME_BOOTTIME_ALARM:
    2836                 :        148 :                 r = s->time.callback(s, s->time.next, s->userdata);
    2837                 :        148 :                 break;
    2838                 :            : 
    2839                 :         20 :         case SOURCE_SIGNAL:
    2840                 :         20 :                 r = s->signal.callback(s, &s->signal.siginfo, s->userdata);
    2841                 :         20 :                 break;
    2842                 :            : 
    2843                 :          4 :         case SOURCE_CHILD: {
    2844                 :            :                 bool zombie;
    2845                 :            : 
    2846         [ +  - ]:          4 :                 zombie = IN_SET(s->child.siginfo.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED);
    2847                 :            : 
    2848                 :          4 :                 r = s->child.callback(s, &s->child.siginfo, s->userdata);
    2849                 :            : 
    2850                 :            :                 /* Now, reap the PID for good. */
    2851         [ +  - ]:          4 :                 if (zombie)
    2852                 :          4 :                         (void) waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|WEXITED);
    2853                 :            : 
    2854                 :          4 :                 break;
    2855                 :            :         }
    2856                 :            : 
    2857                 :       5737 :         case SOURCE_DEFER:
    2858                 :       5737 :                 r = s->defer.callback(s, s->userdata);
    2859                 :       5737 :                 break;
    2860                 :            : 
    2861                 :         12 :         case SOURCE_POST:
    2862                 :         12 :                 r = s->post.callback(s, s->userdata);
    2863                 :         12 :                 break;
    2864                 :            : 
    2865                 :        787 :         case SOURCE_EXIT:
    2866                 :        787 :                 r = s->exit.callback(s, s->userdata);
    2867                 :        787 :                 break;
    2868                 :            : 
    2869                 :     197848 :         case SOURCE_INOTIFY: {
    2870                 :     197848 :                 struct sd_event *e = s->event;
    2871                 :            :                 struct inotify_data *d;
    2872                 :            :                 size_t sz;
    2873                 :            : 
    2874         [ -  + ]:     197848 :                 assert(s->inotify.inode_data);
    2875         [ -  + ]:     197848 :                 assert_se(d = s->inotify.inode_data->inotify_data);
    2876                 :            : 
    2877         [ -  + ]:     197848 :                 assert(d->buffer_filled >= offsetof(struct inotify_event, name));
    2878                 :     197848 :                 sz = offsetof(struct inotify_event, name) + d->buffer.ev.len;
    2879         [ -  + ]:     197848 :                 assert(d->buffer_filled >= sz);
    2880                 :            : 
    2881                 :     197848 :                 r = s->inotify.callback(s, &d->buffer.ev, s->userdata);
    2882                 :            : 
    2883                 :            :                 /* When no event is pending anymore on this inotify object, then let's drop the event from the
    2884                 :            :                  * buffer. */
    2885         [ +  + ]:     197848 :                 if (d->n_pending == 0)
    2886                 :     131900 :                         event_inotify_data_drop(e, d, sz);
    2887                 :            : 
    2888                 :     197848 :                 break;
    2889                 :            :         }
    2890                 :            : 
    2891                 :          0 :         case SOURCE_WATCHDOG:
    2892                 :            :         case _SOURCE_EVENT_SOURCE_TYPE_MAX:
    2893                 :            :         case _SOURCE_EVENT_SOURCE_TYPE_INVALID:
    2894                 :          0 :                 assert_not_reached("Wut? I shouldn't exist.");
    2895                 :            :         }
    2896                 :            : 
    2897                 :     207013 :         s->dispatching = false;
    2898                 :            : 
    2899         [ -  + ]:     207013 :         if (r < 0)
    2900         [ #  # ]:          0 :                 log_debug_errno(r, "Event source %s (type %s) returned error, disabling: %m",
    2901                 :            :                                 strna(s->description), event_source_type_to_string(saved_type));
    2902                 :            : 
    2903         [ +  + ]:     207013 :         if (s->n_ref == 0)
    2904                 :       1944 :                 source_free(s);
    2905         [ -  + ]:     205069 :         else if (r < 0)
    2906                 :          0 :                 sd_event_source_set_enabled(s, SD_EVENT_OFF);
    2907                 :            : 
    2908                 :     207013 :         return 1;
    2909                 :            : }
    2910                 :            : 
    2911                 :     206234 : static int event_prepare(sd_event *e) {
    2912                 :            :         int r;
    2913                 :            : 
    2914         [ -  + ]:     206234 :         assert(e);
    2915                 :            : 
    2916                 :    1435850 :         for (;;) {
    2917                 :            :                 sd_event_source *s;
    2918                 :            : 
    2919                 :    1642084 :                 s = prioq_peek(e->prepare);
    2920   [ +  +  +  +  :    1642084 :                 if (!s || s->prepare_iteration == e->iteration || s->enabled == SD_EVENT_OFF)
                   +  + ]
    2921                 :            :                         break;
    2922                 :            : 
    2923                 :    1435850 :                 s->prepare_iteration = e->iteration;
    2924                 :    1435850 :                 r = prioq_reshuffle(e->prepare, s, &s->prepare_index);
    2925         [ -  + ]:    1435850 :                 if (r < 0)
    2926                 :          0 :                         return r;
    2927                 :            : 
    2928         [ -  + ]:    1435850 :                 assert(s->prepare);
    2929                 :            : 
    2930                 :    1435850 :                 s->dispatching = true;
    2931                 :    1435850 :                 r = s->prepare(s, s->userdata);
    2932                 :    1435850 :                 s->dispatching = false;
    2933                 :            : 
    2934         [ -  + ]:    1435850 :                 if (r < 0)
    2935         [ #  # ]:          0 :                         log_debug_errno(r, "Prepare callback of event source %s (type %s) returned error, disabling: %m",
    2936                 :            :                                         strna(s->description), event_source_type_to_string(s->type));
    2937                 :            : 
    2938         [ -  + ]:    1435850 :                 if (s->n_ref == 0)
    2939                 :          0 :                         source_free(s);
    2940         [ -  + ]:    1435850 :                 else if (r < 0)
    2941                 :          0 :                         sd_event_source_set_enabled(s, SD_EVENT_OFF);
    2942                 :            :         }
    2943                 :            : 
    2944                 :     206234 :         return 0;
    2945                 :            : }
    2946                 :            : 
    2947                 :        847 : static int dispatch_exit(sd_event *e) {
    2948                 :            :         sd_event_source *p;
    2949                 :        847 :         _cleanup_(sd_event_unrefp) sd_event *ref = NULL;
    2950                 :            :         int r;
    2951                 :            : 
    2952         [ -  + ]:        847 :         assert(e);
    2953                 :            : 
    2954                 :        847 :         p = prioq_peek(e->exit);
    2955   [ +  +  +  + ]:        847 :         if (!p || p->enabled == SD_EVENT_OFF) {
    2956                 :         60 :                 e->state = SD_EVENT_FINISHED;
    2957                 :         60 :                 return 0;
    2958                 :            :         }
    2959                 :            : 
    2960                 :        787 :         ref = sd_event_ref(e);
    2961                 :        787 :         e->iteration++;
    2962                 :        787 :         e->state = SD_EVENT_EXITING;
    2963                 :        787 :         r = source_dispatch(p);
    2964                 :        787 :         e->state = SD_EVENT_INITIAL;
    2965                 :        787 :         return r;
    2966                 :            : }
    2967                 :            : 
    2968                 :     618694 : static sd_event_source* event_next_pending(sd_event *e) {
    2969                 :            :         sd_event_source *p;
    2970                 :            : 
    2971         [ -  + ]:     618694 :         assert(e);
    2972                 :            : 
    2973                 :     618694 :         p = prioq_peek(e->pending);
    2974         [ +  + ]:     618694 :         if (!p)
    2975                 :      66304 :                 return NULL;
    2976                 :            : 
    2977         [ +  + ]:     552390 :         if (p->enabled == SD_EVENT_OFF)
    2978                 :        215 :                 return NULL;
    2979                 :            : 
    2980                 :     552175 :         return p;
    2981                 :            : }
    2982                 :            : 
    2983                 :          0 : static int arm_watchdog(sd_event *e) {
    2984                 :          0 :         struct itimerspec its = {};
    2985                 :            :         usec_t t;
    2986                 :            :         int r;
    2987                 :            : 
    2988         [ #  # ]:          0 :         assert(e);
    2989         [ #  # ]:          0 :         assert(e->watchdog_fd >= 0);
    2990                 :            : 
    2991                 :          0 :         t = sleep_between(e,
    2992                 :          0 :                           e->watchdog_last + (e->watchdog_period / 2),
    2993                 :          0 :                           e->watchdog_last + (e->watchdog_period * 3 / 4));
    2994                 :            : 
    2995                 :          0 :         timespec_store(&its.it_value, t);
    2996                 :            : 
    2997                 :            :         /* Make sure we never set the watchdog to 0, which tells the
    2998                 :            :          * kernel to disable it. */
    2999   [ #  #  #  # ]:          0 :         if (its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0)
    3000                 :          0 :                 its.it_value.tv_nsec = 1;
    3001                 :            : 
    3002                 :          0 :         r = timerfd_settime(e->watchdog_fd, TFD_TIMER_ABSTIME, &its, NULL);
    3003         [ #  # ]:          0 :         if (r < 0)
    3004                 :          0 :                 return -errno;
    3005                 :            : 
    3006                 :          0 :         return 0;
    3007                 :            : }
    3008                 :            : 
    3009                 :     206234 : static int process_watchdog(sd_event *e) {
    3010         [ -  + ]:     206234 :         assert(e);
    3011                 :            : 
    3012         [ +  - ]:     206234 :         if (!e->watchdog)
    3013                 :     206234 :                 return 0;
    3014                 :            : 
    3015                 :            :         /* Don't notify watchdog too often */
    3016         [ #  # ]:          0 :         if (e->watchdog_last + e->watchdog_period / 4 > e->timestamp.monotonic)
    3017                 :          0 :                 return 0;
    3018                 :            : 
    3019                 :          0 :         sd_notify(false, "WATCHDOG=1");
    3020                 :          0 :         e->watchdog_last = e->timestamp.monotonic;
    3021                 :            : 
    3022                 :          0 :         return arm_watchdog(e);
    3023                 :            : }
    3024                 :            : 
    3025                 :     206234 : static void event_close_inode_data_fds(sd_event *e) {
    3026                 :            :         struct inode_data *d;
    3027                 :            : 
    3028         [ -  + ]:     206234 :         assert(e);
    3029                 :            : 
    3030                 :            :         /* Close the fds pointing to the inodes to watch now. We need to close them as they might otherwise pin
    3031                 :            :          * filesystems. But we can't close them right-away as we need them as long as the user still wants to make
    3032                 :            :          * adjustments to the even source, such as changing the priority (which requires us to remove and re-add a watch
    3033                 :            :          * for the inode). Hence, let's close them when entering the first iteration after they were added, as a
    3034                 :            :          * compromise. */
    3035                 :            : 
    3036         [ +  + ]:     206258 :         while ((d = e->inode_data_to_close)) {
    3037         [ -  + ]:         24 :                 assert(d->fd >= 0);
    3038                 :         24 :                 d->fd = safe_close(d->fd);
    3039                 :            : 
    3040   [ -  +  +  +  :         24 :                 LIST_REMOVE(to_close, e->inode_data_to_close, d);
             -  +  -  + ]
    3041                 :            :         }
    3042                 :     206234 : }
    3043                 :            : 
    3044                 :     207081 : _public_ int sd_event_prepare(sd_event *e) {
    3045                 :            :         int r;
    3046                 :            : 
    3047   [ -  +  -  + ]:     207081 :         assert_return(e, -EINVAL);
    3048   [ -  +  -  + ]:     207081 :         assert_return(e = event_resolve(e), -ENOPKG);
    3049   [ -  +  -  + ]:     207081 :         assert_return(!event_pid_changed(e), -ECHILD);
    3050   [ -  +  -  + ]:     207081 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
    3051   [ -  +  -  + ]:     207081 :         assert_return(e->state == SD_EVENT_INITIAL, -EBUSY);
    3052                 :            : 
    3053         [ +  + ]:     207081 :         if (e->exit_requested)
    3054                 :        847 :                 goto pending;
    3055                 :            : 
    3056                 :     206234 :         e->iteration++;
    3057                 :            : 
    3058                 :     206234 :         e->state = SD_EVENT_PREPARING;
    3059                 :     206234 :         r = event_prepare(e);
    3060                 :     206234 :         e->state = SD_EVENT_INITIAL;
    3061         [ -  + ]:     206234 :         if (r < 0)
    3062                 :          0 :                 return r;
    3063                 :            : 
    3064                 :     206234 :         r = event_arm_timer(e, &e->realtime);
    3065         [ -  + ]:     206234 :         if (r < 0)
    3066                 :          0 :                 return r;
    3067                 :            : 
    3068                 :     206234 :         r = event_arm_timer(e, &e->boottime);
    3069         [ -  + ]:     206234 :         if (r < 0)
    3070                 :          0 :                 return r;
    3071                 :            : 
    3072                 :     206234 :         r = event_arm_timer(e, &e->monotonic);
    3073         [ -  + ]:     206234 :         if (r < 0)
    3074                 :          0 :                 return r;
    3075                 :            : 
    3076                 :     206234 :         r = event_arm_timer(e, &e->realtime_alarm);
    3077         [ -  + ]:     206234 :         if (r < 0)
    3078                 :          0 :                 return r;
    3079                 :            : 
    3080                 :     206234 :         r = event_arm_timer(e, &e->boottime_alarm);
    3081         [ -  + ]:     206234 :         if (r < 0)
    3082                 :          0 :                 return r;
    3083                 :            : 
    3084                 :     206234 :         event_close_inode_data_fds(e);
    3085                 :            : 
    3086   [ +  +  -  + ]:     206234 :         if (event_next_pending(e) || e->need_process_child)
    3087                 :     139723 :                 goto pending;
    3088                 :            : 
    3089                 :      66511 :         e->state = SD_EVENT_ARMED;
    3090                 :            : 
    3091                 :      66511 :         return 0;
    3092                 :            : 
    3093                 :     140570 : pending:
    3094                 :     140570 :         e->state = SD_EVENT_ARMED;
    3095                 :     140570 :         r = sd_event_wait(e, 0);
    3096         [ -  + ]:     140570 :         if (r == 0)
    3097                 :          0 :                 e->state = SD_EVENT_ARMED;
    3098                 :            : 
    3099                 :     140570 :         return r;
    3100                 :            : }
    3101                 :            : 
    3102                 :     207081 : _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
    3103                 :            :         struct epoll_event *ev_queue;
    3104                 :            :         unsigned ev_queue_max;
    3105                 :            :         int r, m, i;
    3106                 :            : 
    3107   [ -  +  -  + ]:     207081 :         assert_return(e, -EINVAL);
    3108   [ -  +  -  + ]:     207081 :         assert_return(e = event_resolve(e), -ENOPKG);
    3109   [ -  +  -  + ]:     207081 :         assert_return(!event_pid_changed(e), -ECHILD);
    3110   [ -  +  -  + ]:     207081 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
    3111   [ -  +  -  + ]:     207081 :         assert_return(e->state == SD_EVENT_ARMED, -EBUSY);
    3112                 :            : 
    3113         [ +  + ]:     207081 :         if (e->exit_requested) {
    3114                 :        847 :                 e->state = SD_EVENT_PENDING;
    3115                 :        847 :                 return 1;
    3116                 :            :         }
    3117                 :            : 
    3118                 :     206234 :         ev_queue_max = MAX(e->n_sources, 1u);
    3119   [ -  +  -  + ]:     206234 :         ev_queue = newa(struct epoll_event, ev_queue_max);
    3120                 :            : 
    3121                 :            :         /* If we still have inotify data buffered, then query the other fds, but don't wait on it */
    3122         [ +  + ]:     206234 :         if (e->inotify_data_buffered)
    3123                 :     189604 :                 timeout = 0;
    3124                 :            : 
    3125         [ +  + ]:     403705 :         m = epoll_wait(e->epoll_fd, ev_queue, ev_queue_max,
    3126                 :     197471 :                        timeout == (uint64_t) -1 ? -1 : (int) DIV_ROUND_UP(timeout, USEC_PER_MSEC));
    3127         [ -  + ]:     206234 :         if (m < 0) {
    3128         [ #  # ]:          0 :                 if (errno == EINTR) {
    3129                 :          0 :                         e->state = SD_EVENT_PENDING;
    3130                 :          0 :                         return 1;
    3131                 :            :                 }
    3132                 :            : 
    3133                 :          0 :                 r = -errno;
    3134                 :          0 :                 goto finish;
    3135                 :            :         }
    3136                 :            : 
    3137                 :     206234 :         triple_timestamp_get(&e->timestamp);
    3138                 :            : 
    3139         [ +  + ]:    1226002 :         for (i = 0; i < m; i++) {
    3140                 :            : 
    3141         [ -  + ]:    1019768 :                 if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_WATCHDOG))
    3142                 :          0 :                         r = flush_timer(e, e->watchdog_fd, ev_queue[i].events, NULL);
    3143                 :            :                 else {
    3144                 :    1019768 :                         WakeupType *t = ev_queue[i].data.ptr;
    3145                 :            : 
    3146   [ +  +  +  +  :    1019768 :                         switch (*t) {
                      - ]
    3147                 :            : 
    3148                 :     689996 :                         case WAKEUP_EVENT_SOURCE:
    3149                 :     689996 :                                 r = process_io(e, ev_queue[i].data.ptr, ev_queue[i].events);
    3150                 :     689996 :                                 break;
    3151                 :            : 
    3152                 :        156 :                         case WAKEUP_CLOCK_DATA: {
    3153                 :        156 :                                 struct clock_data *d = ev_queue[i].data.ptr;
    3154                 :        156 :                                 r = flush_timer(e, d->fd, ev_queue[i].events, &d->next);
    3155                 :        156 :                                 break;
    3156                 :            :                         }
    3157                 :            : 
    3158                 :         32 :                         case WAKEUP_SIGNAL_DATA:
    3159                 :         32 :                                 r = process_signal(e, ev_queue[i].data.ptr, ev_queue[i].events);
    3160                 :         32 :                                 break;
    3161                 :            : 
    3162                 :     329584 :                         case WAKEUP_INOTIFY_DATA:
    3163                 :     329584 :                                 r = event_inotify_data_read(e, ev_queue[i].data.ptr, ev_queue[i].events);
    3164                 :     329584 :                                 break;
    3165                 :            : 
    3166                 :          0 :                         default:
    3167                 :          0 :                                 assert_not_reached("Invalid wake-up pointer");
    3168                 :            :                         }
    3169                 :            :                 }
    3170         [ -  + ]:    1019768 :                 if (r < 0)
    3171                 :          0 :                         goto finish;
    3172                 :            :         }
    3173                 :            : 
    3174                 :     206234 :         r = process_watchdog(e);
    3175         [ -  + ]:     206234 :         if (r < 0)
    3176                 :          0 :                 goto finish;
    3177                 :            : 
    3178                 :     206234 :         r = process_timer(e, e->timestamp.realtime, &e->realtime);
    3179         [ -  + ]:     206234 :         if (r < 0)
    3180                 :          0 :                 goto finish;
    3181                 :            : 
    3182                 :     206234 :         r = process_timer(e, e->timestamp.boottime, &e->boottime);
    3183         [ -  + ]:     206234 :         if (r < 0)
    3184                 :          0 :                 goto finish;
    3185                 :            : 
    3186                 :     206234 :         r = process_timer(e, e->timestamp.monotonic, &e->monotonic);
    3187         [ -  + ]:     206234 :         if (r < 0)
    3188                 :          0 :                 goto finish;
    3189                 :            : 
    3190                 :     206234 :         r = process_timer(e, e->timestamp.realtime, &e->realtime_alarm);
    3191         [ -  + ]:     206234 :         if (r < 0)
    3192                 :          0 :                 goto finish;
    3193                 :            : 
    3194                 :     206234 :         r = process_timer(e, e->timestamp.boottime, &e->boottime_alarm);
    3195         [ -  + ]:     206234 :         if (r < 0)
    3196                 :          0 :                 goto finish;
    3197                 :            : 
    3198         [ +  + ]:     206234 :         if (e->need_process_child) {
    3199                 :          8 :                 r = process_child(e);
    3200         [ -  + ]:          8 :                 if (r < 0)
    3201                 :          0 :                         goto finish;
    3202                 :            :         }
    3203                 :            : 
    3204                 :     206234 :         r = process_inotify(e);
    3205         [ -  + ]:     206234 :         if (r < 0)
    3206                 :          0 :                 goto finish;
    3207                 :            : 
    3208         [ +  + ]:     206234 :         if (event_next_pending(e)) {
    3209                 :     206226 :                 e->state = SD_EVENT_PENDING;
    3210                 :            : 
    3211                 :     206226 :                 return 1;
    3212                 :            :         }
    3213                 :            : 
    3214                 :          8 :         r = 0;
    3215                 :            : 
    3216                 :          8 : finish:
    3217                 :          8 :         e->state = SD_EVENT_INITIAL;
    3218                 :            : 
    3219                 :          8 :         return r;
    3220                 :            : }
    3221                 :            : 
    3222                 :     207073 : _public_ int sd_event_dispatch(sd_event *e) {
    3223                 :            :         sd_event_source *p;
    3224                 :            :         int r;
    3225                 :            : 
    3226   [ -  +  -  + ]:     207073 :         assert_return(e, -EINVAL);
    3227   [ -  +  -  + ]:     207073 :         assert_return(e = event_resolve(e), -ENOPKG);
    3228   [ -  +  -  + ]:     207073 :         assert_return(!event_pid_changed(e), -ECHILD);
    3229   [ -  +  -  + ]:     207073 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
    3230   [ -  +  -  + ]:     207073 :         assert_return(e->state == SD_EVENT_PENDING, -EBUSY);
    3231                 :            : 
    3232         [ +  + ]:     207073 :         if (e->exit_requested)
    3233                 :        847 :                 return dispatch_exit(e);
    3234                 :            : 
    3235                 :     206226 :         p = event_next_pending(e);
    3236         [ +  - ]:     206226 :         if (p) {
    3237                 :     412452 :                 _cleanup_(sd_event_unrefp) sd_event *ref = NULL;
    3238                 :            : 
    3239                 :     206226 :                 ref = sd_event_ref(e);
    3240                 :     206226 :                 e->state = SD_EVENT_RUNNING;
    3241                 :     206226 :                 r = source_dispatch(p);
    3242                 :     206226 :                 e->state = SD_EVENT_INITIAL;
    3243                 :     206226 :                 return r;
    3244                 :            :         }
    3245                 :            : 
    3246                 :          0 :         e->state = SD_EVENT_INITIAL;
    3247                 :            : 
    3248                 :          0 :         return 1;
    3249                 :            : }
    3250                 :            : 
    3251                 :          0 : static void event_log_delays(sd_event *e) {
    3252                 :            :         char b[ELEMENTSOF(e->delays) * DECIMAL_STR_MAX(unsigned) + 1], *p;
    3253                 :            :         size_t l, i;
    3254                 :            : 
    3255                 :          0 :         p = b;
    3256                 :          0 :         l = sizeof(b);
    3257         [ #  # ]:          0 :         for (i = 0; i < ELEMENTSOF(e->delays); i++) {
    3258                 :          0 :                 l = strpcpyf(&p, l, "%u ", e->delays[i]);
    3259                 :          0 :                 e->delays[i] = 0;
    3260                 :            :         }
    3261         [ #  # ]:          0 :         log_debug("Event loop iterations: %s", b);
    3262                 :          0 : }
    3263                 :            : 
    3264                 :     207081 : _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
    3265                 :            :         int r;
    3266                 :            : 
    3267   [ -  +  -  + ]:     207081 :         assert_return(e, -EINVAL);
    3268   [ -  +  -  + ]:     207081 :         assert_return(e = event_resolve(e), -ENOPKG);
    3269   [ -  +  -  + ]:     207081 :         assert_return(!event_pid_changed(e), -ECHILD);
    3270   [ -  +  -  + ]:     207081 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
    3271   [ -  +  -  + ]:     207081 :         assert_return(e->state == SD_EVENT_INITIAL, -EBUSY);
    3272                 :            : 
    3273   [ -  +  #  # ]:     207081 :         if (e->profile_delays && e->last_run) {
    3274                 :            :                 usec_t this_run;
    3275                 :            :                 unsigned l;
    3276                 :            : 
    3277                 :          0 :                 this_run = now(CLOCK_MONOTONIC);
    3278                 :            : 
    3279                 :          0 :                 l = u64log2(this_run - e->last_run);
    3280         [ #  # ]:          0 :                 assert(l < sizeof(e->delays));
    3281                 :          0 :                 e->delays[l]++;
    3282                 :            : 
    3283         [ #  # ]:          0 :                 if (this_run - e->last_log >= 5*USEC_PER_SEC) {
    3284                 :          0 :                         event_log_delays(e);
    3285                 :          0 :                         e->last_log = this_run;
    3286                 :            :                 }
    3287                 :            :         }
    3288                 :            : 
    3289                 :     207081 :         r = sd_event_prepare(e);
    3290         [ +  + ]:     207081 :         if (r == 0)
    3291                 :            :                 /* There was nothing? Then wait... */
    3292                 :      66511 :                 r = sd_event_wait(e, timeout);
    3293                 :            : 
    3294         [ -  + ]:     207081 :         if (e->profile_delays)
    3295                 :          0 :                 e->last_run = now(CLOCK_MONOTONIC);
    3296                 :            : 
    3297         [ +  + ]:     207081 :         if (r > 0) {
    3298                 :            :                 /* There's something now, then let's dispatch it */
    3299                 :     207073 :                 r = sd_event_dispatch(e);
    3300         [ -  + ]:     207073 :                 if (r < 0)
    3301                 :          0 :                         return r;
    3302                 :            : 
    3303                 :     207073 :                 return 1;
    3304                 :            :         }
    3305                 :            : 
    3306                 :          8 :         return r;
    3307                 :            : }
    3308                 :            : 
    3309                 :         60 : _public_ int sd_event_loop(sd_event *e) {
    3310                 :         60 :         _cleanup_(sd_event_unrefp) sd_event *ref = NULL;
    3311                 :            :         int r;
    3312                 :            : 
    3313   [ -  +  -  + ]:         60 :         assert_return(e, -EINVAL);
    3314   [ -  +  -  + ]:         60 :         assert_return(e = event_resolve(e), -ENOPKG);
    3315   [ -  +  -  + ]:         60 :         assert_return(!event_pid_changed(e), -ECHILD);
    3316   [ -  +  -  + ]:         60 :         assert_return(e->state == SD_EVENT_INITIAL, -EBUSY);
    3317                 :            : 
    3318                 :         60 :         ref = sd_event_ref(e);
    3319                 :            : 
    3320         [ +  + ]:     206886 :         while (e->state != SD_EVENT_FINISHED) {
    3321                 :     206826 :                 r = sd_event_run(e, (uint64_t) -1);
    3322         [ -  + ]:     206826 :                 if (r < 0)
    3323                 :          0 :                         return r;
    3324                 :            :         }
    3325                 :            : 
    3326                 :         60 :         return e->exit_code;
    3327                 :            : }
    3328                 :            : 
    3329                 :          0 : _public_ int sd_event_get_fd(sd_event *e) {
    3330                 :            : 
    3331   [ #  #  #  # ]:          0 :         assert_return(e, -EINVAL);
    3332   [ #  #  #  # ]:          0 :         assert_return(e = event_resolve(e), -ENOPKG);
    3333   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(e), -ECHILD);
    3334                 :            : 
    3335                 :          0 :         return e->epoll_fd;
    3336                 :            : }
    3337                 :            : 
    3338                 :          0 : _public_ int sd_event_get_state(sd_event *e) {
    3339   [ #  #  #  # ]:          0 :         assert_return(e, -EINVAL);
    3340   [ #  #  #  # ]:          0 :         assert_return(e = event_resolve(e), -ENOPKG);
    3341   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(e), -ECHILD);
    3342                 :            : 
    3343                 :          0 :         return e->state;
    3344                 :            : }
    3345                 :            : 
    3346                 :         12 : _public_ int sd_event_get_exit_code(sd_event *e, int *code) {
    3347   [ -  +  -  + ]:         12 :         assert_return(e, -EINVAL);
    3348   [ -  +  -  + ]:         12 :         assert_return(e = event_resolve(e), -ENOPKG);
    3349   [ -  +  -  + ]:         12 :         assert_return(code, -EINVAL);
    3350   [ -  +  -  + ]:         12 :         assert_return(!event_pid_changed(e), -ECHILD);
    3351                 :            : 
    3352         [ -  + ]:         12 :         if (!e->exit_requested)
    3353                 :          0 :                 return -ENODATA;
    3354                 :            : 
    3355                 :         12 :         *code = e->exit_code;
    3356                 :         12 :         return 0;
    3357                 :            : }
    3358                 :            : 
    3359                 :         60 : _public_ int sd_event_exit(sd_event *e, int code) {
    3360   [ -  +  -  + ]:         60 :         assert_return(e, -EINVAL);
    3361   [ -  +  -  + ]:         60 :         assert_return(e = event_resolve(e), -ENOPKG);
    3362   [ -  +  -  + ]:         60 :         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
    3363   [ -  +  -  + ]:         60 :         assert_return(!event_pid_changed(e), -ECHILD);
    3364                 :            : 
    3365                 :         60 :         e->exit_requested = true;
    3366                 :         60 :         e->exit_code = code;
    3367                 :            : 
    3368                 :         60 :         return 0;
    3369                 :            : }
    3370                 :            : 
    3371                 :        232 : _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) {
    3372   [ -  +  -  + ]:        232 :         assert_return(e, -EINVAL);
    3373   [ -  +  -  + ]:        232 :         assert_return(e = event_resolve(e), -ENOPKG);
    3374   [ -  +  -  + ]:        232 :         assert_return(usec, -EINVAL);
    3375   [ -  +  -  + ]:        232 :         assert_return(!event_pid_changed(e), -ECHILD);
    3376                 :            : 
    3377   [ +  +  +  + ]:        232 :         if (!TRIPLE_TIMESTAMP_HAS_CLOCK(clock))
    3378                 :         16 :                 return -EOPNOTSUPP;
    3379                 :            : 
    3380                 :            :         /* Generate a clean error in case CLOCK_BOOTTIME is not available. Note that don't use clock_supported() here,
    3381                 :            :          * for a reason: there are systems where CLOCK_BOOTTIME is supported, but CLOCK_BOOTTIME_ALARM is not, but for
    3382                 :            :          * the purpose of getting the time this doesn't matter. */
    3383   [ +  +  +  +  :        216 :         if (IN_SET(clock, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) && !clock_boottime_supported())
                   -  + ]
    3384                 :          0 :                 return -EOPNOTSUPP;
    3385                 :            : 
    3386         [ +  + ]:        216 :         if (!triple_timestamp_is_set(&e->timestamp)) {
    3387                 :            :                 /* Implicitly fall back to now() if we never ran
    3388                 :            :                  * before and thus have no cached time. */
    3389                 :         44 :                 *usec = now(clock);
    3390                 :         44 :                 return 1;
    3391                 :            :         }
    3392                 :            : 
    3393                 :        172 :         *usec = triple_timestamp_by_clock(&e->timestamp, clock);
    3394                 :        172 :         return 0;
    3395                 :            : }
    3396                 :            : 
    3397                 :        100 : _public_ int sd_event_default(sd_event **ret) {
    3398                 :        100 :         sd_event *e = NULL;
    3399                 :            :         int r;
    3400                 :            : 
    3401         [ -  + ]:        100 :         if (!ret)
    3402                 :          0 :                 return !!default_event;
    3403                 :            : 
    3404         [ -  + ]:        100 :         if (default_event) {
    3405                 :          0 :                 *ret = sd_event_ref(default_event);
    3406                 :          0 :                 return 0;
    3407                 :            :         }
    3408                 :            : 
    3409                 :        100 :         r = sd_event_new(&e);
    3410         [ -  + ]:        100 :         if (r < 0)
    3411                 :          0 :                 return r;
    3412                 :            : 
    3413                 :        100 :         e->default_event_ptr = &default_event;
    3414                 :        100 :         e->tid = gettid();
    3415                 :        100 :         default_event = e;
    3416                 :            : 
    3417                 :        100 :         *ret = e;
    3418                 :        100 :         return 1;
    3419                 :            : }
    3420                 :            : 
    3421                 :          0 : _public_ int sd_event_get_tid(sd_event *e, pid_t *tid) {
    3422   [ #  #  #  # ]:          0 :         assert_return(e, -EINVAL);
    3423   [ #  #  #  # ]:          0 :         assert_return(e = event_resolve(e), -ENOPKG);
    3424   [ #  #  #  # ]:          0 :         assert_return(tid, -EINVAL);
    3425   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(e), -ECHILD);
    3426                 :            : 
    3427         [ #  # ]:          0 :         if (e->tid != 0) {
    3428                 :          0 :                 *tid = e->tid;
    3429                 :          0 :                 return 0;
    3430                 :            :         }
    3431                 :            : 
    3432                 :          0 :         return -ENXIO;
    3433                 :            : }
    3434                 :            : 
    3435                 :         12 : _public_ int sd_event_set_watchdog(sd_event *e, int b) {
    3436                 :            :         int r;
    3437                 :            : 
    3438   [ -  +  -  + ]:         12 :         assert_return(e, -EINVAL);
    3439   [ -  +  -  + ]:         12 :         assert_return(e = event_resolve(e), -ENOPKG);
    3440   [ -  +  -  + ]:         12 :         assert_return(!event_pid_changed(e), -ECHILD);
    3441                 :            : 
    3442         [ -  + ]:         12 :         if (e->watchdog == !!b)
    3443                 :          0 :                 return e->watchdog;
    3444                 :            : 
    3445         [ +  - ]:         12 :         if (b) {
    3446                 :            :                 struct epoll_event ev;
    3447                 :            : 
    3448                 :         12 :                 r = sd_watchdog_enabled(false, &e->watchdog_period);
    3449         [ +  - ]:         12 :                 if (r <= 0)
    3450                 :         12 :                         return r;
    3451                 :            : 
    3452                 :            :                 /* Issue first ping immediately */
    3453                 :          0 :                 sd_notify(false, "WATCHDOG=1");
    3454                 :          0 :                 e->watchdog_last = now(CLOCK_MONOTONIC);
    3455                 :            : 
    3456                 :          0 :                 e->watchdog_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
    3457         [ #  # ]:          0 :                 if (e->watchdog_fd < 0)
    3458                 :          0 :                         return -errno;
    3459                 :            : 
    3460                 :          0 :                 r = arm_watchdog(e);
    3461         [ #  # ]:          0 :                 if (r < 0)
    3462                 :          0 :                         goto fail;
    3463                 :            : 
    3464                 :          0 :                 ev = (struct epoll_event) {
    3465                 :            :                         .events = EPOLLIN,
    3466                 :            :                         .data.ptr = INT_TO_PTR(SOURCE_WATCHDOG),
    3467                 :            :                 };
    3468                 :            : 
    3469                 :          0 :                 r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, e->watchdog_fd, &ev);
    3470         [ #  # ]:          0 :                 if (r < 0) {
    3471                 :          0 :                         r = -errno;
    3472                 :          0 :                         goto fail;
    3473                 :            :                 }
    3474                 :            : 
    3475                 :            :         } else {
    3476         [ #  # ]:          0 :                 if (e->watchdog_fd >= 0) {
    3477                 :          0 :                         epoll_ctl(e->epoll_fd, EPOLL_CTL_DEL, e->watchdog_fd, NULL);
    3478                 :          0 :                         e->watchdog_fd = safe_close(e->watchdog_fd);
    3479                 :            :                 }
    3480                 :            :         }
    3481                 :            : 
    3482                 :          0 :         e->watchdog = !!b;
    3483                 :          0 :         return e->watchdog;
    3484                 :            : 
    3485                 :          0 : fail:
    3486                 :          0 :         e->watchdog_fd = safe_close(e->watchdog_fd);
    3487                 :          0 :         return r;
    3488                 :            : }
    3489                 :            : 
    3490                 :          0 : _public_ int sd_event_get_watchdog(sd_event *e) {
    3491   [ #  #  #  # ]:          0 :         assert_return(e, -EINVAL);
    3492   [ #  #  #  # ]:          0 :         assert_return(e = event_resolve(e), -ENOPKG);
    3493   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(e), -ECHILD);
    3494                 :            : 
    3495                 :          0 :         return e->watchdog;
    3496                 :            : }
    3497                 :            : 
    3498                 :          0 : _public_ int sd_event_get_iteration(sd_event *e, uint64_t *ret) {
    3499   [ #  #  #  # ]:          0 :         assert_return(e, -EINVAL);
    3500   [ #  #  #  # ]:          0 :         assert_return(e = event_resolve(e), -ENOPKG);
    3501   [ #  #  #  # ]:          0 :         assert_return(!event_pid_changed(e), -ECHILD);
    3502                 :            : 
    3503                 :          0 :         *ret = e->iteration;
    3504                 :          0 :         return 0;
    3505                 :            : }
    3506                 :            : 
    3507                 :          0 : _public_ int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback) {
    3508   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    3509                 :            : 
    3510                 :          0 :         s->destroy_callback = callback;
    3511                 :          0 :         return 0;
    3512                 :            : }
    3513                 :            : 
    3514                 :          0 : _public_ int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t *ret) {
    3515   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    3516                 :            : 
    3517         [ #  # ]:          0 :         if (ret)
    3518                 :          0 :                 *ret = s->destroy_callback;
    3519                 :            : 
    3520                 :          0 :         return !!s->destroy_callback;
    3521                 :            : }
    3522                 :            : 
    3523                 :          0 : _public_ int sd_event_source_get_floating(sd_event_source *s) {
    3524   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    3525                 :            : 
    3526                 :          0 :         return s->floating;
    3527                 :            : }
    3528                 :            : 
    3529                 :          0 : _public_ int sd_event_source_set_floating(sd_event_source *s, int b) {
    3530   [ #  #  #  # ]:          0 :         assert_return(s, -EINVAL);
    3531                 :            : 
    3532         [ #  # ]:          0 :         if (s->floating == !!b)
    3533                 :          0 :                 return 0;
    3534                 :            : 
    3535         [ #  # ]:          0 :         if (!s->event) /* Already disconnected */
    3536                 :          0 :                 return -ESTALE;
    3537                 :            : 
    3538                 :          0 :         s->floating = b;
    3539                 :            : 
    3540         [ #  # ]:          0 :         if (b) {
    3541                 :          0 :                 sd_event_source_ref(s);
    3542                 :          0 :                 sd_event_unref(s->event);
    3543                 :            :         } else {
    3544                 :          0 :                 sd_event_ref(s->event);
    3545                 :          0 :                 sd_event_source_unref(s);
    3546                 :            :         }
    3547                 :            : 
    3548                 :          0 :         return 1;
    3549                 :            : }

Generated by: LCOV version 1.14