592caf
From d7ad6ad123200f562081ff09f7bed3c6d969ac0a Mon Sep 17 00:00:00 2001
592caf
From: Lennart Poettering <lennart@poettering.net>
592caf
Date: Fri, 23 Oct 2020 21:21:58 +0200
592caf
Subject: [PATCH] sd-event: split out enable and disable codepaths from
592caf
 sd_event_source_set_enabled()
592caf
MIME-Version: 1.0
592caf
Content-Type: text/plain; charset=UTF-8
592caf
Content-Transfer-Encoding: 8bit
592caf
592caf
So far half of sd_event_source_set_enabled() was doing enabling, the
592caf
other half was doing disabling. Let's split that into two separate
592caf
calls.
592caf
592caf
(This also adds a new shortcut to sd_event_source_set_enabled(): if the
592caf
caller toggles between "ON" and "ONESHOT" we'll now shortcut this, since
592caf
the event source is already enabled in that case and shall remain
592caf
enabled.)
592caf
592caf
This heavily borrows and is inspired from Michal Sekletár's #17284
592caf
refactoring.
592caf
592caf
(cherry picked from commit ddfde737b546c17e54182028153aa7f7e78804e3)
592caf
592caf
Related: #1819868
592caf
---
592caf
 src/libsystemd/sd-event/sd-event.c | 227 +++++++++++++++--------------
592caf
 1 file changed, 121 insertions(+), 106 deletions(-)
592caf
592caf
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
592caf
index 47f99eb096..df5ed0dce8 100644
592caf
--- a/src/libsystemd/sd-event/sd-event.c
592caf
+++ b/src/libsystemd/sd-event/sd-event.c
592caf
@@ -2260,152 +2260,167 @@ _public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) {
592caf
         return 0;
592caf
 }
592caf
 
592caf
-_public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
592caf
+static int event_source_disable(sd_event_source *s) {
592caf
         int r;
592caf
 
592caf
-        assert_return(s, -EINVAL);
592caf
-        assert_return(IN_SET(m, SD_EVENT_OFF, SD_EVENT_ON, SD_EVENT_ONESHOT), -EINVAL);
592caf
-        assert_return(!event_pid_changed(s->event), -ECHILD);
592caf
+        assert(s);
592caf
+        assert(s->enabled != SD_EVENT_OFF);
592caf
 
592caf
-        /* If we are dead anyway, we are fine with turning off
592caf
-         * sources, but everything else needs to fail. */
592caf
-        if (s->event->state == SD_EVENT_FINISHED)
592caf
-                return m == SD_EVENT_OFF ? 0 : -ESTALE;
592caf
+        /* Unset the pending flag when this event source is disabled */
592caf
+        if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
592caf
+                r = source_set_pending(s, false);
592caf
+                if (r < 0)
592caf
+                        return r;
592caf
+        }
592caf
 
592caf
-        if (s->enabled == m)
592caf
-                return 0;
592caf
+        s->enabled = SD_EVENT_OFF;
592caf
 
592caf
-        if (m == SD_EVENT_OFF) {
592caf
+        switch (s->type) {
592caf
 
592caf
-                /* Unset the pending flag when this event source is disabled */
592caf
-                if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
592caf
-                        r = source_set_pending(s, false);
592caf
-                        if (r < 0)
592caf
-                                return r;
592caf
-                }
592caf
+        case SOURCE_IO:
592caf
+                source_io_unregister(s);
592caf
+                break;
592caf
 
592caf
-                switch (s->type) {
592caf
+        case SOURCE_TIME_REALTIME:
592caf
+        case SOURCE_TIME_BOOTTIME:
592caf
+        case SOURCE_TIME_MONOTONIC:
592caf
+        case SOURCE_TIME_REALTIME_ALARM:
592caf
+        case SOURCE_TIME_BOOTTIME_ALARM:
592caf
+                event_source_time_prioq_reshuffle(s);
592caf
+                break;
592caf
 
592caf
-                case SOURCE_IO:
592caf
-                        source_io_unregister(s);
592caf
-                        s->enabled = m;
592caf
-                        break;
592caf
+        case SOURCE_SIGNAL:
592caf
+                event_gc_signal_data(s->event, &s->priority, s->signal.sig);
592caf
+                break;
592caf
 
592caf
-                case SOURCE_TIME_REALTIME:
592caf
-                case SOURCE_TIME_BOOTTIME:
592caf
-                case SOURCE_TIME_MONOTONIC:
592caf
-                case SOURCE_TIME_REALTIME_ALARM:
592caf
-                case SOURCE_TIME_BOOTTIME_ALARM:
592caf
-                        s->enabled = m;
592caf
-                        event_source_time_prioq_reshuffle(s);
592caf
-                        break;
592caf
+        case SOURCE_CHILD:
592caf
+                assert(s->event->n_enabled_child_sources > 0);
592caf
+                s->event->n_enabled_child_sources--;
592caf
 
592caf
-                case SOURCE_SIGNAL:
592caf
-                        s->enabled = m;
592caf
+                event_gc_signal_data(s->event, &s->priority, SIGCHLD);
592caf
+                break;
592caf
 
592caf
-                        event_gc_signal_data(s->event, &s->priority, s->signal.sig);
592caf
-                        break;
592caf
+        case SOURCE_EXIT:
592caf
+                prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
592caf
+                break;
592caf
 
592caf
-                case SOURCE_CHILD:
592caf
-                        s->enabled = m;
592caf
+        case SOURCE_DEFER:
592caf
+        case SOURCE_POST:
592caf
+        case SOURCE_INOTIFY:
592caf
+                break;
592caf
 
592caf
-                        assert(s->event->n_enabled_child_sources > 0);
592caf
-                        s->event->n_enabled_child_sources--;
592caf
+        default:
592caf
+                assert_not_reached("Wut? I shouldn't exist.");
592caf
+        }
592caf
 
592caf
-                        event_gc_signal_data(s->event, &s->priority, SIGCHLD);
592caf
-                        break;
592caf
+        return 0;
592caf
+}
592caf
 
592caf
-                case SOURCE_EXIT:
592caf
-                        s->enabled = m;
592caf
-                        prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
592caf
-                        break;
592caf
+static int event_source_enable(sd_event_source *s, int m) {
592caf
+        int r;
592caf
 
592caf
-                case SOURCE_DEFER:
592caf
-                case SOURCE_POST:
592caf
-                case SOURCE_INOTIFY:
592caf
-                        s->enabled = m;
592caf
-                        break;
592caf
+        assert(s);
592caf
+        assert(IN_SET(m, SD_EVENT_ON, SD_EVENT_ONESHOT));
592caf
+        assert(s->enabled == SD_EVENT_OFF);
592caf
 
592caf
-                default:
592caf
-                        assert_not_reached("Wut? I shouldn't exist.");
592caf
-                }
592caf
+        /* Unset the pending flag when this event source is enabled */
592caf
+        if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
592caf
+                r = source_set_pending(s, false);
592caf
+                if (r < 0)
592caf
+                        return r;
592caf
+        }
592caf
 
592caf
-        } else {
592caf
+        s->enabled = m;
592caf
 
592caf
-                /* Unset the pending flag when this event source is enabled */
592caf
-                if (s->enabled == SD_EVENT_OFF && !IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
592caf
-                        r = source_set_pending(s, false);
592caf
-                        if (r < 0)
592caf
-                                return r;
592caf
+        switch (s->type) {
592caf
+
592caf
+        case SOURCE_IO:
592caf
+                r = source_io_register(s, m, s->io.events);
592caf
+                if (r < 0) {
592caf
+                        s->enabled = SD_EVENT_OFF;
592caf
+                        return r;
592caf
                 }
592caf
 
592caf
-                switch (s->type) {
592caf
+                break;
592caf
 
592caf
-                case SOURCE_IO:
592caf
-                        r = source_io_register(s, m, s->io.events);
592caf
-                        if (r < 0)
592caf
-                                return r;
592caf
+        case SOURCE_TIME_REALTIME:
592caf
+        case SOURCE_TIME_BOOTTIME:
592caf
+        case SOURCE_TIME_MONOTONIC:
592caf
+        case SOURCE_TIME_REALTIME_ALARM:
592caf
+        case SOURCE_TIME_BOOTTIME_ALARM:
592caf
+                event_source_time_prioq_reshuffle(s);
592caf
+                break;
592caf
 
592caf
-                        s->enabled = m;
592caf
-                        break;
592caf
+        case SOURCE_SIGNAL:
592caf
+                r = event_make_signal_data(s->event, s->signal.sig, NULL);
592caf
+                if (r < 0) {
592caf
+                        s->enabled = SD_EVENT_OFF;
592caf
+                        event_gc_signal_data(s->event, &s->priority, s->signal.sig);
592caf
+                        return r;
592caf
+                }
592caf
 
592caf
-                case SOURCE_TIME_REALTIME:
592caf
-                case SOURCE_TIME_BOOTTIME:
592caf
-                case SOURCE_TIME_MONOTONIC:
592caf
-                case SOURCE_TIME_REALTIME_ALARM:
592caf
-                case SOURCE_TIME_BOOTTIME_ALARM:
592caf
-                        s->enabled = m;
592caf
-                        event_source_time_prioq_reshuffle(s);
592caf
-                        break;
592caf
+                break;
592caf
 
592caf
-                case SOURCE_SIGNAL:
592caf
+        case SOURCE_CHILD:
592caf
+                s->event->n_enabled_child_sources++;
592caf
 
592caf
-                        s->enabled = m;
592caf
+                r = event_make_signal_data(s->event, SIGCHLD, NULL);
592caf
+                if (r < 0) {
592caf
+                        s->enabled = SD_EVENT_OFF;
592caf
+                        s->event->n_enabled_child_sources--;
592caf
+                        event_gc_signal_data(s->event, &s->priority, SIGCHLD);
592caf
+                        return r;
592caf
+                }
592caf
 
592caf
-                        r = event_make_signal_data(s->event, s->signal.sig, NULL);
592caf
-                        if (r < 0) {
592caf
-                                s->enabled = SD_EVENT_OFF;
592caf
-                                event_gc_signal_data(s->event, &s->priority, s->signal.sig);
592caf
-                                return r;
592caf
-                        }
592caf
 
592caf
-                        break;
592caf
+                break;
592caf
 
592caf
-                case SOURCE_CHILD:
592caf
+        case SOURCE_EXIT:
592caf
+                prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
592caf
+                break;
592caf
 
592caf
-                        if (s->enabled == SD_EVENT_OFF)
592caf
-                                s->event->n_enabled_child_sources++;
592caf
+        case SOURCE_DEFER:
592caf
+        case SOURCE_POST:
592caf
+        case SOURCE_INOTIFY:
592caf
+                break;
592caf
 
592caf
-                        s->enabled = m;
592caf
+        default:
592caf
+                assert_not_reached("Wut? I shouldn't exist.");
592caf
+        }
592caf
 
592caf
-                        r = event_make_signal_data(s->event, SIGCHLD, NULL);
592caf
-                        if (r < 0) {
592caf
-                                s->enabled = SD_EVENT_OFF;
592caf
-                                s->event->n_enabled_child_sources--;
592caf
-                                event_gc_signal_data(s->event, &s->priority, SIGCHLD);
592caf
-                                return r;
592caf
-                        }
592caf
+        return 0;
592caf
+}
592caf
 
592caf
-                        break;
592caf
+_public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
592caf
+        int r;
592caf
 
592caf
-                case SOURCE_EXIT:
592caf
-                        s->enabled = m;
592caf
-                        prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
592caf
-                        break;
592caf
+        assert_return(s, -EINVAL);
592caf
+        assert_return(IN_SET(m, SD_EVENT_OFF, SD_EVENT_ON, SD_EVENT_ONESHOT), -EINVAL);
592caf
+        assert_return(!event_pid_changed(s->event), -ECHILD);
592caf
 
592caf
-                case SOURCE_DEFER:
592caf
-                case SOURCE_POST:
592caf
-                case SOURCE_INOTIFY:
592caf
-                        s->enabled = m;
592caf
-                        break;
592caf
+        /* If we are dead anyway, we are fine with turning off sources, but everything else needs to fail. */
592caf
+        if (s->event->state == SD_EVENT_FINISHED)
592caf
+                return m == SD_EVENT_OFF ? 0 : -ESTALE;
592caf
 
592caf
-                default:
592caf
-                        assert_not_reached("Wut? I shouldn't exist.");
592caf
+        if (s->enabled == m) /* No change? */
592caf
+                return 0;
592caf
+
592caf
+        if (m == SD_EVENT_OFF)
592caf
+                r = event_source_disable(s);
592caf
+        else {
592caf
+                if (s->enabled != SD_EVENT_OFF) {
592caf
+                        /* Switching from "on" to "oneshot" or back? If that's the case, we can take a shortcut, the
592caf
+                         * event source is already enabled after all. */
592caf
+                        s->enabled = m;
592caf
+                        return 0;
592caf
                 }
592caf
+
592caf
+                r = event_source_enable(s, m);
592caf
         }
592caf
+        if (r < 0)
592caf
+                return r;
592caf
 
592caf
         event_source_pp_prioq_reshuffle(s);
592caf
-
592caf
         return 0;
592caf
 }
592caf