When a child event is disabled (in order to be freed) and there is no SIGCHLD signal event, sd_event_source_set_enabled will disable SIGCHLD even if there are other child events. My fix also removes some unneeded signalfd updates. diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index b56182d..42b176b 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -1055,11 +1055,9 @@ _public_ int sd_event_add_child( return r; } - e->n_enabled_child_sources ++; - assert_se(sigaddset(&e->sigset, SIGCHLD) == 0); - if (!e->signal_sources || !e->signal_sources[SIGCHLD]) { + if ((!e->signal_sources || !e->signal_sources[SIGCHLD]) && e->n_enabled_child_sources == 0) { r = event_update_signal_fd(e); if (r < 0) { source_free(s); @@ -1067,6 +1065,8 @@ _public_ int sd_event_add_child( } } + e->n_enabled_child_sources ++; + e->need_process_child = true; if (ret) @@ -1451,7 +1451,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { assert(s->event->n_enabled_child_sources > 0); s->event->n_enabled_child_sources--; - if (!s->event->signal_sources || !s->event->signal_sources[SIGCHLD]) { + if ((!s->event->signal_sources || !s->event->signal_sources[SIGCHLD]) && s->event->n_enabled_child_sources == 0) { assert_se(sigdelset(&s->event->sigset, SIGCHLD) == 0); event_update_signal_fd(s->event); } @@ -1511,12 +1511,12 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { case SOURCE_CHILD: if (s->enabled == SD_EVENT_OFF) { - s->event->n_enabled_child_sources++; - - if (!s->event->signal_sources || !s->event->signal_sources[SIGCHLD]) { + if ((!s->event->signal_sources || !s->event->signal_sources[SIGCHLD]) && s->event->n_enabled_child_sources == 0) { assert_se(sigaddset(&s->event->sigset, SIGCHLD) == 0); event_update_signal_fd(s->event); } + + s->event->n_enabled_child_sources++; } s->enabled = m;
A more extensive fix based on this patch applied as http://cgit.freedesktop.org/systemd/systemd/commit/?id=4807d2d068.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.