]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/libsystemd/sd-event/sd-event.c
libsystemd: use IN_SET macro
[thirdparty/systemd.git] / src / libsystemd / sd-event / sd-event.c
index eeb3453919e97440ad0997f1ecef4f4a8966187b..2c5c2ebb4dc40a88736bda5d6b99fe62f28ccce4 100644 (file)
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
 /***
   This file is part of systemd.
 
@@ -111,8 +109,8 @@ struct sd_event_source {
         int64_t priority;
         unsigned pending_index;
         unsigned prepare_index;
-        unsigned pending_iteration;
-        unsigned prepare_iteration;
+        uint64_t pending_iteration;
+        uint64_t prepare_iteration;
 
         LIST_FIELDS(sd_event_source, sources);
 
@@ -217,9 +215,8 @@ struct sd_event {
 
         pid_t original_pid;
 
-        unsigned iteration;
-        dual_timestamp timestamp;
-        usec_t timestamp_boottime;
+        uint64_t iteration;
+        triple_timestamp timestamp;
         int state;
 
         bool exit_requested:1;
@@ -439,7 +436,7 @@ _public_ int sd_event_new(sd_event** ret) {
         e->watchdog_fd = e->epoll_fd = e->realtime.fd = e->boottime.fd = e->monotonic.fd = e->realtime_alarm.fd = e->boottime_alarm.fd = -1;
         e->realtime.next = e->boottime.next = e->monotonic.next = e->realtime_alarm.next = e->boottime_alarm.next = USEC_INFINITY;
         e->realtime.wakeup = e->boottime.wakeup = e->monotonic.wakeup = e->realtime_alarm.wakeup = e->boottime_alarm.wakeup = WAKEUP_CLOCK_DATA;
-        e->original_pid = getpid();
+        e->original_pid = getpid_cached();
         e->perturb = USEC_INFINITY;
 
         r = prioq_ensure_allocated(&e->pending, pending_prioq_compare);
@@ -496,7 +493,7 @@ static bool event_pid_changed(sd_event *e) {
         /* We don't support people creating an event loop and keeping
          * it around over a fork(). Let's complain. */
 
-        return e->original_pid != getpid();
+        return e->original_pid != getpid_cached();
 }
 
 static void source_io_unregister(sd_event_source *s) {
@@ -733,7 +730,6 @@ static void event_unmask_signal_data(sd_event *e, struct signal_data *d, int sig
 
                 /* If all the mask is all-zero we can get rid of the structure */
                 hashmap_remove(e->signal_data, &d->priority);
-                assert(!d->current);
                 safe_close(d->fd);
                 free(d);
                 return;
@@ -953,7 +949,7 @@ static sd_event_source *source_new(sd_event *e, bool floating, EventSourceType t
                 sd_event_ref(e);
 
         LIST_PREPEND(sources, e->sources, s);
-        e->n_sources ++;
+        e->n_sources++;
 
         return s;
 }
@@ -1074,12 +1070,16 @@ _public_ int sd_event_add_time(
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
+        if (!clock_supported(clock)) /* Checks whether the kernel supports the clock */
+                return -EOPNOTSUPP;
+
+        type = clock_to_event_source_type(clock); /* checks whether sd-event supports this clock */
+        if (type < 0)
+                return -EOPNOTSUPP;
+
         if (!callback)
                 callback = time_exit_callback;
 
-        type = clock_to_event_source_type(clock);
-        assert_return(type >= 0, -EOPNOTSUPP);
-
         d = event_get_clock_data(e, type);
         assert(d);
 
@@ -1147,8 +1147,7 @@ _public_ int sd_event_add_signal(
         int r;
 
         assert_return(e, -EINVAL);
-        assert_return(sig > 0, -EINVAL);
-        assert_return(sig < _NSIG, -EINVAL);
+        assert_return(SIGNAL_VALID(sig), -EINVAL);
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
@@ -1237,7 +1236,7 @@ _public_ int sd_event_add_child(
                 return r;
         }
 
-        e->n_enabled_child_sources ++;
+        e->n_enabled_child_sources++;
 
         r = event_make_signal_data(e, SIGCHLD, NULL);
         if (r < 0) {
@@ -1539,7 +1538,8 @@ _public_ int sd_event_source_get_priority(sd_event_source *s, int64_t *priority)
         assert_return(s, -EINVAL);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
-        return s->priority;
+        *priority = s->priority;
+        return 0;
 }
 
 _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) {
@@ -1597,7 +1597,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
         int r;
 
         assert_return(s, -EINVAL);
-        assert_return(m == SD_EVENT_OFF || m == SD_EVENT_ON || m == SD_EVENT_ONESHOT, -EINVAL);
+        assert_return(IN_SET(m, SD_EVENT_OFF, SD_EVENT_ON, SD_EVENT_ONESHOT), -EINVAL);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
         /* If we are dead anyway, we are fine with turning off
@@ -2050,7 +2050,7 @@ static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) {
 
         ss = read(fd, &x, sizeof(x));
         if (ss < 0) {
-                if (errno == EAGAIN || errno == EINTR)
+                if (IN_SET(errno, EAGAIN, EINTR))
                         return 0;
 
                 return -errno;
@@ -2139,10 +2139,7 @@ static int process_child(sd_event *e) {
                         return -errno;
 
                 if (s->child.siginfo.si_pid != 0) {
-                        bool zombie =
-                                s->child.siginfo.si_code == CLD_EXITED ||
-                                s->child.siginfo.si_code == CLD_KILLED ||
-                                s->child.siginfo.si_code == CLD_DUMPED;
+                        bool zombie = IN_SET(s->child.siginfo.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED);
 
                         if (!zombie && (s->child.options & WEXITED)) {
                                 /* If the child isn't dead then let's
@@ -2193,7 +2190,7 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
 
                 n = read(d->fd, &si, sizeof(si));
                 if (n < 0) {
-                        if (errno == EAGAIN || errno == EINTR)
+                        if (IN_SET(errno, EAGAIN, EINTR))
                                 return read_one;
 
                         return -errno;
@@ -2202,7 +2199,7 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
                 if (_unlikely_(n != sizeof(si)))
                         return -EIO;
 
-                assert(si.ssi_signo < _NSIG);
+                assert(SIGNAL_VALID(si.ssi_signo));
 
                 read_one = true;
 
@@ -2225,12 +2222,17 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
 }
 
 static int source_dispatch(sd_event_source *s) {
+        EventSourceType saved_type;
         int r = 0;
 
         assert(s);
         assert(s->pending || s->type == SOURCE_EXIT);
 
-        if (s->type != SOURCE_DEFER && s->type != SOURCE_EXIT) {
+        /* Save the event source type, here, so that we still know it after the event callback which might invalidate
+         * the event. */
+        saved_type = s->type;
+
+        if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
                 r = source_set_pending(s, false);
                 if (r < 0)
                         return r;
@@ -2282,9 +2284,7 @@ static int source_dispatch(sd_event_source *s) {
         case SOURCE_CHILD: {
                 bool zombie;
 
-                zombie = s->child.siginfo.si_code == CLD_EXITED ||
-                         s->child.siginfo.si_code == CLD_KILLED ||
-                         s->child.siginfo.si_code == CLD_DUMPED;
+                zombie = IN_SET(s->child.siginfo.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED);
 
                 r = s->child.callback(s, &s->child.siginfo, s->userdata);
 
@@ -2317,7 +2317,7 @@ static int source_dispatch(sd_event_source *s) {
 
         if (r < 0)
                 log_debug_errno(r, "Event source %s (type %s) returned error, disabling: %m",
-                                strna(s->description), event_source_type_to_string(s->type));
+                                strna(s->description), event_source_type_to_string(saved_type));
 
         if (s->n_ref == 0)
                 source_free(s);
@@ -2529,8 +2529,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
                 goto finish;
         }
 
-        dual_timestamp_get(&e->timestamp);
-        e->timestamp_boottime = now(CLOCK_BOOTTIME);
+        triple_timestamp_get(&e->timestamp);
 
         for (i = 0; i < m; i++) {
 
@@ -2571,7 +2570,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
         if (r < 0)
                 goto finish;
 
-        r = process_timer(e, e->timestamp_boottime, &e->boottime);
+        r = process_timer(e, e->timestamp.boottime, &e->boottime);
         if (r < 0)
                 goto finish;
 
@@ -2583,7 +2582,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
         if (r < 0)
                 goto finish;
 
-        r = process_timer(e, e->timestamp_boottime, &e->boottime_alarm);
+        r = process_timer(e, e->timestamp.boottime, &e->boottime_alarm);
         if (r < 0)
                 goto finish;
 
@@ -2757,36 +2756,24 @@ _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) {
         assert_return(e, -EINVAL);
         assert_return(usec, -EINVAL);
         assert_return(!event_pid_changed(e), -ECHILD);
-        assert_return(IN_SET(clock,
-                             CLOCK_REALTIME,
-                             CLOCK_REALTIME_ALARM,
-                             CLOCK_MONOTONIC,
-                             CLOCK_BOOTTIME,
-                             CLOCK_BOOTTIME_ALARM), -EOPNOTSUPP);
-
-        if (!dual_timestamp_is_set(&e->timestamp)) {
+
+        if (!TRIPLE_TIMESTAMP_HAS_CLOCK(clock))
+                return -EOPNOTSUPP;
+
+        /* Generate a clean error in case CLOCK_BOOTTIME is not available. Note that don't use clock_supported() here,
+         * for a reason: there are systems where CLOCK_BOOTTIME is supported, but CLOCK_BOOTTIME_ALARM is not, but for
+         * the purpose of getting the time this doesn't matter. */
+        if (IN_SET(clock, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) && !clock_boottime_supported())
+                return -EOPNOTSUPP;
+
+        if (!triple_timestamp_is_set(&e->timestamp)) {
                 /* Implicitly fall back to now() if we never ran
                  * before and thus have no cached time. */
                 *usec = now(clock);
                 return 1;
         }
 
-        switch (clock) {
-
-        case CLOCK_REALTIME:
-        case CLOCK_REALTIME_ALARM:
-                *usec = e->timestamp.realtime;
-                break;
-
-        case CLOCK_MONOTONIC:
-                *usec = e->timestamp.monotonic;
-                break;
-
-        default:
-                *usec = e->timestamp_boottime;
-                break;
-        }
-
+        *usec = triple_timestamp_by_clock(&e->timestamp, clock);
         return 0;
 }
 
@@ -2887,3 +2874,11 @@ _public_ int sd_event_get_watchdog(sd_event *e) {
 
         return e->watchdog;
 }
+
+_public_ int sd_event_get_iteration(sd_event *e, uint64_t *ret) {
+        assert_return(e, -EINVAL);
+        assert_return(!event_pid_changed(e), -ECHILD);
+
+        *ret = e->iteration;
+        return 0;
+}