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