diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2014-10-04 23:17:45 -0400 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2014-10-08 19:30:22 -0400 |
commit | f95387cda829bc053992c398789ce3aa6f42f81e (patch) | |
tree | 2e7cbb252394c8096a0fe5b14e2989093f9e8686 /src | |
parent | 4807d2d068ae9fc08b87121fc0a574394f8acc5b (diff) |
sd-event: also update signal mask when disconnecting sources
Diffstat (limited to 'src')
-rw-r--r-- | src/libsystemd/sd-event/sd-event.c | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index c5f062b3e0..80a2ae97e8 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -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. */ } } @@ -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); |