chiark / gitweb /
Fix service file to match installed elogind binary location
[elogind.git] / src / libelogind / sd-event / sd-event.c
index 192dc0ea6980898fcefd2744cbad303ad3ba9cf1..b4686d0065b1a943312735bf11f15b4d6b0ebac0 100644 (file)
@@ -109,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);
 
@@ -215,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;
@@ -547,7 +546,6 @@ static int source_io_register(
         return 0;
 }
 
-#if 0 /// UNNEEDED by elogind
 static clockid_t event_source_type_to_clock(EventSourceType t) {
 
         switch (t) {
@@ -571,7 +569,6 @@ static clockid_t event_source_type_to_clock(EventSourceType t) {
                 return (clockid_t) -1;
         }
 }
-#endif // 0
 
 static EventSourceType clock_to_event_source_type(clockid_t clock) {
 
@@ -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;
@@ -1074,16 +1070,16 @@ _public_ int sd_event_add_time(
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
-        if (IN_SET(clock, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) &&
-            !clock_boottime_supported())
+        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);
 
@@ -1198,7 +1194,6 @@ _public_ int sd_event_add_signal(
         return 0;
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ int sd_event_add_child(
                 sd_event *e,
                 sd_event_source **ret,
@@ -1291,7 +1286,6 @@ _public_ int sd_event_add_defer(
 
         return 0;
 }
-#endif // 0
 
 _public_ int sd_event_add_post(
                 sd_event *e,
@@ -1370,7 +1364,6 @@ _public_ int sd_event_add_exit(
         return 0;
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ sd_event_source* sd_event_source_ref(sd_event_source *s) {
 
         if (!s)
@@ -1381,7 +1374,6 @@ _public_ sd_event_source* sd_event_source_ref(sd_event_source *s) {
 
         return s;
 }
-#endif // 0
 
 _public_ sd_event_source* sd_event_source_unref(sd_event_source *s) {
 
@@ -1419,7 +1411,6 @@ _public_ int sd_event_source_set_description(sd_event_source *s, const char *des
         return free_and_strdup(&s->description, description);
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ int sd_event_source_get_description(sd_event_source *s, const char **description) {
         assert_return(s, -EINVAL);
         assert_return(description, -EINVAL);
@@ -1429,7 +1420,6 @@ _public_ int sd_event_source_get_description(sd_event_source *s, const char **de
         *description = s->description;
         return 0;
 }
-#endif // 0
 
 _public_ sd_event *sd_event_source_get_event(sd_event_source *s) {
         assert_return(s, NULL);
@@ -1437,7 +1427,6 @@ _public_ sd_event *sd_event_source_get_event(sd_event_source *s) {
         return s->event;
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ int sd_event_source_get_pending(sd_event_source *s) {
         assert_return(s, -EINVAL);
         assert_return(s->type != SOURCE_EXIT, -EDOM);
@@ -1454,7 +1443,6 @@ _public_ int sd_event_source_get_io_fd(sd_event_source *s) {
 
         return s->io.fd;
 }
-#endif // 0
 
 _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) {
         int r;
@@ -1492,7 +1480,6 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) {
         return 0;
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) {
         assert_return(s, -EINVAL);
         assert_return(events, -EINVAL);
@@ -1502,7 +1489,6 @@ _public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events)
         *events = s->io.events;
         return 0;
 }
-#endif // 0
 
 _public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) {
         int r;
@@ -1529,7 +1515,6 @@ _public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events)
         return 0;
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents) {
         assert_return(s, -EINVAL);
         assert_return(revents, -EINVAL);
@@ -1553,9 +1538,9 @@ _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;
 }
-#endif // 0
 
 _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) {
         int r;
@@ -1599,7 +1584,6 @@ _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority)
         return 0;
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) {
         assert_return(s, -EINVAL);
         assert_return(m, -EINVAL);
@@ -1608,7 +1592,6 @@ _public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) {
         *m = s->enabled;
         return 0;
 }
-#endif // 0
 
 _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
         int r;
@@ -1794,7 +1777,6 @@ _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
         return 0;
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) {
         assert_return(s, -EINVAL);
         assert_return(usec, -EINVAL);
@@ -1849,7 +1831,6 @@ _public_ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) {
         *pid = s->child.pid;
         return 0;
 }
-#endif // 0
 
 _public_ int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback) {
         int r;
@@ -1883,7 +1864,6 @@ _public_ int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t
         return 0;
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ void* sd_event_source_get_userdata(sd_event_source *s) {
         assert_return(s, NULL);
 
@@ -1900,7 +1880,6 @@ _public_ void *sd_event_source_set_userdata(sd_event_source *s, void *userdata)
 
         return ret;
 }
-#endif // 0
 
 static usec_t sleep_between(sd_event *e, usec_t a, usec_t b) {
         usec_t c;
@@ -2246,11 +2225,16 @@ 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);
 
+        /* 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 (s->type != SOURCE_DEFER && s->type != SOURCE_EXIT) {
                 r = source_set_pending(s, false);
                 if (r < 0)
@@ -2338,7 +2322,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);
@@ -2550,9 +2534,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
                 goto finish;
         }
 
-        dual_timestamp_get(&e->timestamp);
-        if (clock_boottime_supported())
-                e->timestamp_boottime = now(CLOCK_BOOTTIME);
+        triple_timestamp_get(&e->timestamp);
 
         for (i = 0; i < m; i++) {
 
@@ -2593,7 +2575,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;
 
@@ -2605,7 +2587,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;
 
@@ -2715,7 +2697,6 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
         return r;
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ int sd_event_loop(sd_event *e) {
         int r;
 
@@ -2745,7 +2726,6 @@ _public_ int sd_event_get_fd(sd_event *e) {
 
         return e->epoll_fd;
 }
-#endif // 0
 
 _public_ int sd_event_get_state(sd_event *e) {
         assert_return(e, -EINVAL);
@@ -2754,7 +2734,6 @@ _public_ int sd_event_get_state(sd_event *e) {
         return e->state;
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ int sd_event_get_exit_code(sd_event *e, int *code) {
         assert_return(e, -EINVAL);
         assert_return(code, -EINVAL);
@@ -2766,7 +2745,6 @@ _public_ int sd_event_get_exit_code(sd_event *e, int *code) {
         *code = e->exit_code;
         return 0;
 }
-#endif // 0
 
 _public_ int sd_event_exit(sd_event *e, int code) {
         assert_return(e, -EINVAL);
@@ -2779,51 +2757,30 @@ _public_ int sd_event_exit(sd_event *e, int code) {
         return 0;
 }
 
-#if 0 /// UNNEEDED by elogind
 _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 (!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 (!dual_timestamp_is_set(&e->timestamp)) {
+        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;
-
-        case CLOCK_BOOTTIME:
-        case CLOCK_BOOTTIME_ALARM:
-                *usec = e->timestamp_boottime;
-                break;
-
-        default:
-                assert_not_reached("Unknown clock?");
-        }
-
+        *usec = triple_timestamp_by_clock(&e->timestamp, clock);
         return 0;
 }
-#endif // 0
 
 _public_ int sd_event_default(sd_event **ret) {
 
@@ -2851,7 +2808,6 @@ _public_ int sd_event_default(sd_event **ret) {
         return 1;
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ int sd_event_get_tid(sd_event *e, pid_t *tid) {
         assert_return(e, -EINVAL);
         assert_return(tid, -EINVAL);
@@ -2864,7 +2820,6 @@ _public_ int sd_event_get_tid(sd_event *e, pid_t *tid) {
 
         return -ENXIO;
 }
-#endif // 0
 
 _public_ int sd_event_set_watchdog(sd_event *e, int b) {
         int r;
@@ -2918,11 +2873,17 @@ fail:
         return r;
 }
 
-#if 0 /// UNNEEDED by elogind
 _public_ int sd_event_get_watchdog(sd_event *e) {
         assert_return(e, -EINVAL);
         assert_return(!event_pid_changed(e), -ECHILD);
 
         return e->watchdog;
 }
-#endif // 0
+
+_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;
+}