From d6a83dc48ad1981665ff427858ae8e59d4cfd6cb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 28 Jul 2020 11:17:00 +0200 Subject: [PATCH] sd-event: add relative timer calls We frequently want to set a timer relative to the current time. Let's add an explicit API for this. This not only saves us a few lines of code everywhere and simplifies things, but also allows us to do correct overflow checking. --- src/libsystemd/libsystemd.sym | 6 +++++ src/libsystemd/sd-event/sd-event.c | 42 ++++++++++++++++++++++++++++++ src/systemd/sd-event.h | 2 ++ 3 files changed, 50 insertions(+) diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 1e654b49ea3..3168a4dcc4f 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -721,3 +721,9 @@ global: sd_journal_enumerate_available_data; sd_journal_enumerate_available_unique; } LIBSYSTEMD_245; + +LIBSYSTEMD_247 { +global: + sd_event_add_time_relative; + sd_event_source_set_time_relative; +} LIBSYSTEMD_246; diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 860eb048ff5..8b338f5db6c 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -1146,6 +1146,31 @@ _public_ int sd_event_add_time( return 0; } +_public_ int sd_event_add_time_relative( + sd_event *e, + sd_event_source **ret, + clockid_t clock, + uint64_t usec, + uint64_t accuracy, + sd_event_time_handler_t callback, + void *userdata) { + + usec_t t; + int r; + + /* Same as sd_event_add_time() but operates relative to the event loop's current point in time, and + * checks for overflow. */ + + r = sd_event_now(e, clock, &t); + if (r < 0) + return r; + + if (usec >= USEC_INFINITY - t) + return -EOVERFLOW; + + return sd_event_add_time(e, ret, clock, t + usec, accuracy, callback, userdata); +} + static int signal_exit_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { assert(s); @@ -2402,6 +2427,23 @@ _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) { return 0; } +_public_ int sd_event_source_set_time_relative(sd_event_source *s, uint64_t usec) { + usec_t t; + int r; + + assert_return(s, -EINVAL); + assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM); + + r = sd_event_now(s->event, event_source_type_to_clock(s->type), &t); + if (r < 0) + return r; + + if (usec >= USEC_INFINITY - t) + return -EOVERFLOW; + + return sd_event_source_set_time(s, t + usec); +} + _public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) { assert_return(s, -EINVAL); assert_return(usec, -EINVAL); diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h index 2ec726a897a..dc96bfa6817 100644 --- a/src/systemd/sd-event.h +++ b/src/systemd/sd-event.h @@ -88,6 +88,7 @@ sd_event* sd_event_unref(sd_event *e); int sd_event_add_io(sd_event *e, sd_event_source **s, int fd, uint32_t events, sd_event_io_handler_t callback, void *userdata); int sd_event_add_time(sd_event *e, sd_event_source **s, clockid_t clock, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, void *userdata); +int sd_event_add_time_relative(sd_event *e, sd_event_source **s, clockid_t clock, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, void *userdata); int sd_event_add_signal(sd_event *e, sd_event_source **s, int sig, sd_event_signal_handler_t callback, void *userdata); int sd_event_add_child(sd_event *e, sd_event_source **s, pid_t pid, int options, sd_event_child_handler_t callback, void *userdata); int sd_event_add_child_pidfd(sd_event *e, sd_event_source **s, int pidfd, int options, sd_event_child_handler_t callback, void *userdata); @@ -138,6 +139,7 @@ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events); int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents); int sd_event_source_get_time(sd_event_source *s, uint64_t *usec); int sd_event_source_set_time(sd_event_source *s, uint64_t usec); +int sd_event_source_set_time_relative(sd_event_source *s, uint64_t usec); int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec); int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec); int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock); -- 2.39.2