chiark / gitweb /
sd-bus,sd-event: unify error handling of object descriptions
[elogind.git] / src / libsystemd / sd-event / sd-event.c
index c5f062b3e00409bd4f2d20dc67cfc4ae2e87a4b7..fb436adc13a971a6bbfebb99caa8cb11f3cb8583 100644 (file)
@@ -66,7 +66,7 @@ struct sd_event_source {
         void *userdata;
         sd_event_handler_t prepare;
 
-        char *name;
+        char *description;
 
         EventSourceType type:5;
         int enabled:3;
@@ -598,6 +598,36 @@ static bool need_signal(sd_event *e, int signal) {
                 e->n_enabled_child_sources > 0);
 }
 
+static int event_update_signal_fd(sd_event *e) {
+        struct epoll_event ev = {};
+        bool add_to_epoll;
+        int r;
+
+        assert(e);
+
+        add_to_epoll = e->signal_fd < 0;
+
+        r = signalfd(e->signal_fd, &e->sigset, SFD_NONBLOCK|SFD_CLOEXEC);
+        if (r < 0)
+                return -errno;
+
+        e->signal_fd = r;
+
+        if (!add_to_epoll)
+                return 0;
+
+        ev.events = EPOLLIN;
+        ev.data.ptr = INT_TO_PTR(SOURCE_SIGNAL);
+
+        r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, e->signal_fd, &ev);
+        if (r < 0) {
+                e->signal_fd = safe_close(e->signal_fd);
+                return -errno;
+        }
+
+        return 0;
+}
+
 static void source_disconnect(sd_event_source *s) {
         sd_event *event;
 
@@ -640,6 +670,10 @@ static void source_disconnect(sd_event_source *s) {
                         /* If the signal was on and now it is off... */
                         if (s->enabled != SD_EVENT_OFF && !need_signal(s->event, s->signal.sig)) {
                                 assert_se(sigdelset(&s->event->sigset, s->signal.sig) == 0);
+
+                                (void) event_update_signal_fd(s->event);
+                                /* If disabling failed, we might get a spurious event,
+                                 * but otherwise nothing bad should happen. */
                         }
                 }
 
@@ -654,6 +688,10 @@ static void source_disconnect(sd_event_source *s) {
                                 /* We know the signal was on, if it is off now... */
                                 if (!need_signal(s->event, SIGCHLD)) {
                                         assert_se(sigdelset(&s->event->sigset, SIGCHLD) == 0);
+
+                                        (void) event_update_signal_fd(s->event);
+                                        /* If disabling failed, we might get a spurious event,
+                                         * but otherwise nothing bad should happen. */
                                 }
                         }
 
@@ -699,7 +737,7 @@ static void source_free(sd_event_source *s) {
         assert(s);
 
         source_disconnect(s);
-        free(s->name);
+        free(s->description);
         free(s);
 }
 
@@ -929,36 +967,6 @@ fail:
         return r;
 }
 
-static int event_update_signal_fd(sd_event *e) {
-        struct epoll_event ev = {};
-        bool add_to_epoll;
-        int r;
-
-        assert(e);
-
-        add_to_epoll = e->signal_fd < 0;
-
-        r = signalfd(e->signal_fd, &e->sigset, SFD_NONBLOCK|SFD_CLOEXEC);
-        if (r < 0)
-                return -errno;
-
-        e->signal_fd = r;
-
-        if (!add_to_epoll)
-                return 0;
-
-        ev.events = EPOLLIN;
-        ev.data.ptr = INT_TO_PTR(SOURCE_SIGNAL);
-
-        r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, e->signal_fd, &ev);
-        if (r < 0) {
-                e->signal_fd = safe_close(e->signal_fd);
-                return -errno;
-        }
-
-        return 0;
-}
-
 static int signal_exit_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
         assert(s);
 
@@ -1023,6 +1031,9 @@ _public_ int sd_event_add_signal(
                 }
         }
 
+        /* Use the signal name as description for the event source by default */
+        (void) sd_event_source_set_description(s, signal_to_string(sig));
+
         if (ret)
                 *ret = s;
 
@@ -1245,18 +1256,20 @@ _public_ sd_event_source* sd_event_source_unref(sd_event_source *s) {
         return NULL;
 }
 
-_public_ int sd_event_source_set_name(sd_event_source *s, const char *name) {
+_public_ int sd_event_source_set_description(sd_event_source *s, const char *description) {
         assert_return(s, -EINVAL);
+        assert_return(!event_pid_changed(s->event), -ECHILD);
 
-        return free_and_strdup(&s->name, name);
+        return free_and_strdup(&s->description, description);
 }
 
-_public_ int sd_event_source_get_name(sd_event_source *s, const char **name) {
+_public_ int sd_event_source_get_description(sd_event_source *s, const char **description) {
         assert_return(s, -EINVAL);
-        assert_return(name, -EINVAL);
-
-        *name = s->name;
+        assert_return(description, -EINVAL);
+        assert_return(s->description, -ENXIO);
+        assert_return(!event_pid_changed(s->event), -ECHILD);
 
+        *description = s->description;
         return 0;
 }
 
@@ -2144,8 +2157,8 @@ static int source_dispatch(sd_event_source *s) {
         s->dispatching = false;
 
         if (r < 0) {
-                if (s->name)
-                        log_debug("Event source '%s' returned error, disabling: %s", s->name, strerror(-r));
+                if (s->description)
+                        log_debug("Event source '%s' returned error, disabling: %s", s->description, strerror(-r));
                 else
                         log_debug("Event source %p returned error, disabling: %s", s, strerror(-r));
         }
@@ -2182,8 +2195,8 @@ static int event_prepare(sd_event *e) {
                 s->dispatching = false;
 
                 if (r < 0) {
-                        if (s->name)
-                                log_debug("Prepare callback of event source '%s' returned error, disabling: %s", s->name, strerror(-r));
+                        if (s->description)
+                                log_debug("Prepare callback of event source '%s' returned error, disabling: %s", s->description, strerror(-r));
                         else
                                 log_debug("Prepare callback of event source %p returned error, disabling: %s", s, strerror(-r));
                 }