From 7e2bf71ca3638e36ee33215ceee386ba8013da6d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 15 Jun 2021 00:44:04 +0900 Subject: [PATCH 1/5] sd-event: drop unnecessary "else" --- src/libsystemd/sd-event/sd-event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 489878a3e9..930dc743e2 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -2983,8 +2983,8 @@ static int event_arm_timer( if (!d->needs_rearm) return 0; - else - d->needs_rearm = false; + + d->needs_rearm = false; a = prioq_peek(d->earliest); if (!a || a->enabled == SD_EVENT_OFF || time_event_source_next(a) == USEC_INFINITY) { From 06e131477d82b83c5d516e66d6e413affd7c774a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 15 Jun 2021 00:51:33 +0900 Subject: [PATCH 2/5] sd-event: use CMP() macro --- src/libsystemd/sd-event/sd-event.c | 37 ++++++++++++++---------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 930dc743e2..e6744989ff 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -168,10 +168,9 @@ static int pending_prioq_compare(const void *a, const void *b) { assert(y->pending); /* Enabled ones first */ - if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) - return -1; - if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) - return 1; + r = CMP(x->enabled == SD_EVENT_OFF, y->enabled == SD_EVENT_OFF); + if (r != 0) + return r; /* Non rate-limited ones first. */ r = CMP(!!x->ratelimited, !!y->ratelimited); @@ -195,10 +194,9 @@ static int prepare_prioq_compare(const void *a, const void *b) { assert(y->prepare); /* Enabled ones first */ - if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) - return -1; - if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) - return 1; + r = CMP(x->enabled == SD_EVENT_OFF, y->enabled == SD_EVENT_OFF); + if (r != 0) + return r; /* Non rate-limited ones first. */ r = CMP(!!x->ratelimited, !!y->ratelimited); @@ -265,18 +263,17 @@ static bool event_source_timer_candidate(const sd_event_source *s) { static int time_prioq_compare(const void *a, const void *b, usec_t (*time_func)(const sd_event_source *s)) { const sd_event_source *x = a, *y = b; + int r; /* Enabled ones first */ - if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) - return -1; - if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) - return 1; + r = CMP(x->enabled == SD_EVENT_OFF, y->enabled == SD_EVENT_OFF); + if (r != 0) + return r; /* Order "non-pending OR ratelimited" before "pending AND not-ratelimited" */ - if (event_source_timer_candidate(x) && !event_source_timer_candidate(y)) - return -1; - if (!event_source_timer_candidate(x) && event_source_timer_candidate(y)) - return 1; + r = CMP(!event_source_timer_candidate(x), !event_source_timer_candidate(y)); + if (r != 0) + return r; /* Order by time */ return CMP(time_func(x), time_func(y)); @@ -292,15 +289,15 @@ static int latest_time_prioq_compare(const void *a, const void *b) { static int exit_prioq_compare(const void *a, const void *b) { const sd_event_source *x = a, *y = b; + int r; assert(x->type == SOURCE_EXIT); assert(y->type == SOURCE_EXIT); /* Enabled ones first */ - if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF) - return -1; - if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF) - return 1; + r = CMP(x->enabled == SD_EVENT_OFF, y->enabled == SD_EVENT_OFF); + if (r != 0) + return r; /* Lower priority values first */ return CMP(x->priority, y->priority); From a595fb5ca9c69c589e758e9ebe3b70ac90450ba3 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 15 Jun 2021 01:01:48 +0900 Subject: [PATCH 3/5] sd-event: use usec_add() --- src/libsystemd/sd-event/sd-event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index e6744989ff..b2c2074e81 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -3677,8 +3677,8 @@ static int arm_watchdog(sd_event *e) { assert(e->watchdog_fd >= 0); t = sleep_between(e, - e->watchdog_last + (e->watchdog_period / 2), - e->watchdog_last + (e->watchdog_period * 3 / 4)); + usec_add(e->watchdog_last, (e->watchdog_period / 2)), + usec_add(e->watchdog_last, (e->watchdog_period * 3 / 4))); timespec_store(&its.it_value, t); From 5c08c7ab23dbf02aaf4e4bbae8e08a195da230a4 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 15 Jun 2021 02:03:02 +0900 Subject: [PATCH 4/5] sd-event: make event_source_time_prioq_reshuffle() accept all event source type But it does nothing for an event source which is neither a timer nor ratelimited. --- src/libsystemd/sd-event/sd-event.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index b2c2074e81..bf27fff84c 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -771,14 +771,15 @@ static void event_source_time_prioq_reshuffle(sd_event_source *s) { assert(s); /* Called whenever the event source's timer ordering properties changed, i.e. time, accuracy, - * pending, enable state. Makes sure the two prioq's are ordered properly again. */ + * pending, enable state, and ratelimiting state. Makes sure the two prioq's are ordered + * properly again. */ if (s->ratelimited) d = &s->event->monotonic; - else { - assert(EVENT_SOURCE_IS_TIME(s->type)); + else if (EVENT_SOURCE_IS_TIME(s->type)) assert_se(d = event_get_clock_data(s->event, s->type)); - } + else + return; /* no-op for an event source which is neither a timer nor ratelimited. */ prioq_reshuffle(d->earliest, s, &s->earliest_index); prioq_reshuffle(d->latest, s, &s->latest_index); From 2115b9b6629eeba7bc9f42f757f38205febb1cb7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 15 Jun 2021 02:13:59 +0900 Subject: [PATCH 5/5] sd-event: always reshuffle time prioq on changing online/offline state Before 81107b8419c39f726fd2805517a5b9faab204e59, the compare functions for the latest or earliest prioq did not handle ratelimited flag. So, it was ok to not reshuffle the time prioq when changing the flag. But now, those two compare functions also compare the source is ratelimited or not. So, it is necessary to reshuffle the time prioq after changing the ratelimited flag. Hopefully fixes #19903. --- src/libsystemd/sd-event/sd-event.c | 33 ++++++++++-------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index bf27fff84c..cc9d9f5d9b 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -2370,14 +2370,6 @@ static int event_source_offline( source_io_unregister(s); break; - case SOURCE_TIME_REALTIME: - case SOURCE_TIME_BOOTTIME: - case SOURCE_TIME_MONOTONIC: - case SOURCE_TIME_REALTIME_ALARM: - case SOURCE_TIME_BOOTTIME_ALARM: - event_source_time_prioq_reshuffle(s); - break; - case SOURCE_SIGNAL: event_gc_signal_data(s->event, &s->priority, s->signal.sig); break; @@ -2398,6 +2390,11 @@ static int event_source_offline( prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); break; + case SOURCE_TIME_REALTIME: + case SOURCE_TIME_BOOTTIME: + case SOURCE_TIME_MONOTONIC: + case SOURCE_TIME_REALTIME_ALARM: + case SOURCE_TIME_BOOTTIME_ALARM: case SOURCE_DEFER: case SOURCE_POST: case SOURCE_INOTIFY: @@ -2407,6 +2404,9 @@ static int event_source_offline( assert_not_reached("Wut? I shouldn't exist."); } + /* Always reshuffle time prioq, as the ratelimited flag may be changed. */ + event_source_time_prioq_reshuffle(s); + return 1; } @@ -2496,22 +2496,11 @@ static int event_source_online( s->ratelimited = ratelimited; /* Non-failing operations below */ - switch (s->type) { - case SOURCE_TIME_REALTIME: - case SOURCE_TIME_BOOTTIME: - case SOURCE_TIME_MONOTONIC: - case SOURCE_TIME_REALTIME_ALARM: - case SOURCE_TIME_BOOTTIME_ALARM: - event_source_time_prioq_reshuffle(s); - break; - - case SOURCE_EXIT: + if (s->type == SOURCE_EXIT) prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index); - break; - default: - break; - } + /* Always reshuffle time prioq, as the ratelimited flag may be changed. */ + event_source_time_prioq_reshuffle(s); return 1; }