X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fsd-event.c;h=19fa982ed391356784eeebc5ac669fe8f11173d2;hb=fe8245eb3c4bc4c492168b861ce3b631479a9046;hp=96ba2ad269cc10cc02f4d3ff20704ba619c15952;hpb=46e8c8257f5dd0bcf964eb1f5cbb9ce43aac5201;p=elogind.git diff --git a/src/libsystemd-bus/sd-event.c b/src/libsystemd-bus/sd-event.c index 96ba2ad26..19fa982ed 100644 --- a/src/libsystemd-bus/sd-event.c +++ b/src/libsystemd-bus/sd-event.c @@ -493,6 +493,10 @@ static void source_free(sd_event_source *s) { break; + case SOURCE_DEFER: + /* nothing */ + break; + case SOURCE_QUIT: prioq_remove(s->event->quit, s, &s->quit.prioq_index); break; @@ -998,7 +1002,7 @@ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) { return 0; if (s->enabled != SD_EVENT_OFF) { - r = source_io_register(s, s->io.events, events); + r = source_io_register(s, s->enabled, events); if (r < 0) return r; } @@ -1380,8 +1384,20 @@ static int event_arm_timer( assert_se(next); a = prioq_peek(earliest); - if (!a || a->enabled == SD_EVENT_OFF) + if (!a || a->enabled == SD_EVENT_OFF) { + + if (*next == (usec_t) -1) + return 0; + + /* disarm */ + r = timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &its, NULL); + if (r < 0) + return r; + + *next = (usec_t) -1; + return 0; + } b = prioq_peek(latest); assert_se(b && b->enabled != SD_EVENT_OFF); @@ -1426,12 +1442,14 @@ static int process_io(sd_event *e, sd_event_source *s, uint32_t events) { return source_set_pending(s, true); } -static int flush_timer(sd_event *e, int fd, uint32_t events) { +static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) { uint64_t x; ssize_t ss; assert(e); assert(fd >= 0); + assert(next); + assert_return(events == EPOLLIN, -EIO); ss = read(fd, &x, sizeof(x)); @@ -1445,6 +1463,8 @@ static int flush_timer(sd_event *e, int fd, uint32_t events) { if (ss != sizeof(x)) return -EIO; + *next = (usec_t) -1; + return 0; } @@ -1526,15 +1546,17 @@ static int process_child(sd_event *e) { } static int process_signal(sd_event *e, uint32_t events) { - struct signalfd_siginfo si; bool read_one = false; - ssize_t ss; int r; assert(e); + assert(e->signal_sources); + assert_return(events == EPOLLIN, -EIO); for (;;) { + struct signalfd_siginfo si; + ssize_t ss; sd_event_source *s; ss = read(e->signal_fd, &si, sizeof(si)); @@ -1550,17 +1572,16 @@ static int process_signal(sd_event *e, uint32_t events) { read_one = true; + s = e->signal_sources[si.ssi_signo]; if (si.ssi_signo == SIGCHLD) { r = process_child(e); if (r < 0) return r; - if (r > 0 || !e->signal_sources[si.ssi_signo]) + if (r > 0 || !s) continue; - } else { - s = e->signal_sources[si.ssi_signo]; + } else if (!s) return -EIO; - } s->signal.siginfo = si; r = source_set_pending(s, true); @@ -1573,7 +1594,7 @@ static int process_signal(sd_event *e, uint32_t events) { } static int source_dispatch(sd_event_source *s) { - int r; + int r = 0; assert(s); assert(s->pending || s->type == SOURCE_QUIT); @@ -1727,7 +1748,7 @@ int sd_event_run(sd_event *e, uint64_t timeout) { m = epoll_wait(e->epoll_fd, ev_queue, EPOLL_QUEUE_MAX, timeout == (uint64_t) -1 ? -1 : (int) ((timeout + USEC_PER_MSEC - 1) / USEC_PER_MSEC)); if (m < 0) { - r = m; + r = errno == EAGAIN || errno == EINTR ? 0 : -errno; goto finish; } @@ -1736,9 +1757,9 @@ int sd_event_run(sd_event *e, uint64_t timeout) { for (i = 0; i < m; i++) { if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_MONOTONIC)) - r = flush_timer(e, e->monotonic_fd, ev_queue[i].events); + r = flush_timer(e, e->monotonic_fd, ev_queue[i].events, &e->monotonic_next); else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_REALTIME)) - r = flush_timer(e, e->realtime_fd, ev_queue[i].events); + r = flush_timer(e, e->realtime_fd, ev_queue[i].events, &e->realtime_next); else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_SIGNAL)) r = process_signal(e, ev_queue[i].events); else