X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fsd-event.c;h=3599d90eb41b683d253f28e1cb6e4c4d9b265716;hb=e471512768bc0c5c3809178ff42c67e10da25f34;hp=3094d9e297e9ab82e04fe35797ca111a63e87fd6;hpb=baf762833224267ef5380fb83b22f294628695a8;p=elogind.git diff --git a/src/libsystemd-bus/sd-event.c b/src/libsystemd-bus/sd-event.c index 3094d9e29..3599d90eb 100644 --- a/src/libsystemd-bus/sd-event.c +++ b/src/libsystemd-bus/sd-event.c @@ -133,6 +133,7 @@ struct sd_event { pid_t original_pid; unsigned iteration; + dual_timestamp timestamp; int state; bool quit_requested:1; @@ -333,8 +334,7 @@ int sd_event_new(sd_event** ret) { sd_event *e; int r; - if (!ret) - return -EINVAL; + assert_return(ret, -EINVAL); e = new0(sd_event, 1); if (!e) @@ -368,8 +368,7 @@ fail: } sd_event* sd_event_ref(sd_event *e) { - if (!e) - return NULL; + assert_return(e, NULL); assert(e->n_ref >= 1); e->n_ref++; @@ -378,8 +377,7 @@ sd_event* sd_event_ref(sd_event *e) { } sd_event* sd_event_unref(sd_event *e) { - if (!e) - return NULL; + assert_return(e, NULL); assert(e->n_ref >= 1); e->n_ref--; @@ -416,7 +414,11 @@ static int source_io_unregister(sd_event_source *s) { return 0; } -static int source_io_register(sd_event_source *s, int enabled, uint32_t events) { +static int source_io_register( + sd_event_source *s, + int enabled, + uint32_t events) { + struct epoll_event ev = {}; int r; @@ -491,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; @@ -561,19 +567,13 @@ int sd_event_add_io( sd_event_source *s; int r; - if (!e) - return -EINVAL; - if (fd < 0) - return -EINVAL; - if (events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP)) - return -EINVAL; - if (!callback) - return -EINVAL; - if (!ret) - return -EINVAL; + assert_return(e, -EINVAL); + assert_return(fd >= 0, -EINVAL); + assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP)), -EINVAL); + assert_return(callback, -EINVAL); + assert_return(ret, -EINVAL); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); - if (event_pid_changed(e)) - return -ECHILD; + assert_return(!event_pid_changed(e), -ECHILD); s = source_new(e, SOURCE_IO); if (!s) @@ -655,19 +655,13 @@ static int event_add_time_internal( sd_event_source *s; int r; - if (!e) - return -EINVAL; - if (!callback) - return -EINVAL; - if (!ret) - return -EINVAL; - if (usec == (uint64_t) -1) - return -EINVAL; - if (accuracy == (uint64_t) -1) - return -EINVAL; + assert_return(e, -EINVAL); + assert_return(callback, -EINVAL); + assert_return(ret, -EINVAL); + assert_return(usec != (uint64_t) -1, -EINVAL); + assert_return(accuracy != (uint64_t) -1, -EINVAL); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); - if (event_pid_changed(e)) - return -ECHILD; + assert_return(!event_pid_changed(e), -ECHILD); assert(timer_fd); assert(earliest); @@ -758,23 +752,23 @@ static int event_update_signal_fd(sd_event *e) { return 0; } -int sd_event_add_signal(sd_event *e, int sig, sd_signal_handler_t callback, void *userdata, sd_event_source **ret) { +int sd_event_add_signal( + sd_event *e, + int sig, + sd_signal_handler_t callback, + void *userdata, + sd_event_source **ret) { + sd_event_source *s; int r; - if (!e) - return -EINVAL; - if (sig <= 0) - return -EINVAL; - if (sig >= _NSIG) - return -EINVAL; - if (!callback) - return -EINVAL; - if (!ret) - return -EINVAL; + assert_return(e, -EINVAL); + assert_return(sig > 0, -EINVAL); + assert_return(sig < _NSIG, -EINVAL); + assert_return(callback, -EINVAL); + assert_return(ret, -EINVAL); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); - if (event_pid_changed(e)) - return -ECHILD; + assert_return(!event_pid_changed(e), -ECHILD); if (!e->signal_sources) { e->signal_sources = new0(sd_event_source*, _NSIG); @@ -807,23 +801,25 @@ int sd_event_add_signal(sd_event *e, int sig, sd_signal_handler_t callback, void return 0; } -int sd_event_add_child(sd_event *e, pid_t pid, int options, sd_child_handler_t callback, void *userdata, sd_event_source **ret) { +int sd_event_add_child( + sd_event *e, + pid_t pid, + int options, + sd_child_handler_t callback, + void *userdata, + sd_event_source **ret) { + sd_event_source *s; int r; - if (!e) - return -EINVAL; - if (pid <= 1) - return -EINVAL; - if (options & ~(WEXITED|WSTOPPED|WCONTINUED)) - return -EINVAL; - if (!callback) - return -EINVAL; - if (!ret) - return -EINVAL; + assert_return(e, -EINVAL); + assert_return(pid > 1, -EINVAL); + assert_return(!(options & ~(WEXITED|WSTOPPED|WCONTINUED)), -EINVAL); + assert_return(options != 0, -EINVAL); + assert_return(callback, -EINVAL); + assert_return(ret, -EINVAL); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); - if (event_pid_changed(e)) - return -ECHILD; + assert_return(!event_pid_changed(e), -ECHILD); r = hashmap_ensure_allocated(&e->child_sources, trivial_hash_func, trivial_compare_func); if (r < 0) @@ -866,17 +862,20 @@ int sd_event_add_child(sd_event *e, pid_t pid, int options, sd_child_handler_t c return 0; } -int sd_event_add_defer(sd_event *e, sd_defer_handler_t callback, void *userdata, sd_event_source **ret) { +int sd_event_add_defer( + sd_event *e, + sd_defer_handler_t callback, + void *userdata, + sd_event_source **ret) { + sd_event_source *s; int r; - if (!e) - return -EINVAL; - if (!ret) - return -EINVAL; + assert_return(e, -EINVAL); + assert_return(callback, -EINVAL); + assert_return(ret, -EINVAL); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); - if (event_pid_changed(e)) - return -ECHILD; + assert_return(!event_pid_changed(e), -ECHILD); s = source_new(e, SOURCE_DEFER); if (!s) @@ -896,12 +895,18 @@ int sd_event_add_defer(sd_event *e, sd_defer_handler_t callback, void *userdata, return 0; } -int sd_event_add_quit(sd_event *e, sd_quit_handler_t callback, void *userdata, sd_event_source **ret) { +int sd_event_add_quit( + sd_event *e, + sd_quit_handler_t callback, + void *userdata, + sd_event_source **ret) { + sd_event_source *s; int r; assert_return(e, -EINVAL); assert_return(callback, -EINVAL); + assert_return(ret, -EINVAL); assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); assert_return(!event_pid_changed(e), -ECHILD); @@ -952,42 +957,33 @@ sd_event_source* sd_event_source_unref(sd_event_source *s) { } sd_event *sd_event_get(sd_event_source *s) { - if (!s) - return NULL; + assert_return(s, NULL); return s->event; } int sd_event_source_get_pending(sd_event_source *s) { - if (!s) - return -EINVAL; + assert_return(s, -EINVAL); + assert_return(s->type != SOURCE_QUIT, -EDOM); assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE); - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(!event_pid_changed(s->event), -ECHILD); return s->pending; } int sd_event_source_get_io_fd(sd_event_source *s) { - if (!s) - return -EINVAL; - if (s->type != SOURCE_IO) - return -EDOM; - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(s, -EINVAL); + assert_return(s->type == SOURCE_IO, -EDOM); + assert_return(!event_pid_changed(s->event), -ECHILD); return s->io.fd; } int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) { - if (!s) - return -EINVAL; - if (s->type != SOURCE_IO) - return -EDOM; - if (!events) - return -EINVAL; - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(s, -EINVAL); + assert_return(events, -EINVAL); + assert_return(s->type == SOURCE_IO, -EDOM); + assert_return(!event_pid_changed(s->event), -ECHILD); *events = s->io.events; return 0; @@ -996,21 +992,17 @@ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) { int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) { int r; - if (!s) - return -EINVAL; - if (!s->type != SOURCE_IO) - return -EDOM; - if (events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP)) - return -EINVAL; + assert_return(s, -EINVAL); + assert_return(s->type == SOURCE_IO, -EDOM); + assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP)), -EINVAL); assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE); - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(!event_pid_changed(s->event), -ECHILD); if (s->io.events == 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; } @@ -1021,48 +1013,35 @@ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) { } int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents) { - if (!s) - return -EINVAL; - if (s->type != SOURCE_IO) - return -EDOM; - if (!revents) - return -EINVAL; - if (!s->pending) - return -ENODATA; - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(s, -EINVAL); + assert_return(revents, -EINVAL); + assert_return(s->type == SOURCE_IO, -EDOM); + assert_return(s->pending, -ENODATA); + assert_return(!event_pid_changed(s->event), -ECHILD); *revents = s->io.revents; return 0; } int sd_event_source_get_signal(sd_event_source *s) { - if (!s) - return -EINVAL; - if (s->type != SOURCE_SIGNAL) - return -EDOM; - assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE); - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(s, -EINVAL); + assert_return(s->type == SOURCE_SIGNAL, -EDOM); + assert_return(!event_pid_changed(s->event), -ECHILD); return s->signal.sig; } int sd_event_source_get_priority(sd_event_source *s, int *priority) { - if (!s) - return -EINVAL; - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(s, -EINVAL); + assert_return(!event_pid_changed(s->event), -ECHILD); return s->priority; } int sd_event_source_set_priority(sd_event_source *s, int priority) { - if (!s) - return -EINVAL; + assert_return(s, -EINVAL); assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE); - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(!event_pid_changed(s->event), -ECHILD); if (s->priority == priority) return 0; @@ -1075,16 +1054,16 @@ int sd_event_source_set_priority(sd_event_source *s, int priority) { if (s->prepare) prioq_reshuffle(s->event->prepare, s, &s->prepare_index); + if (s->type == SOURCE_QUIT) + prioq_reshuffle(s->event->quit, s, &s->quit.prioq_index); + return 0; } int sd_event_source_get_enabled(sd_event_source *s, int *m) { - if (!s) - return -EINVAL; - if (!m) - return -EINVAL; - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(s, -EINVAL); + assert_return(m, -EINVAL); + assert_return(!event_pid_changed(s->event), -ECHILD); *m = s->enabled; return 0; @@ -1093,13 +1072,10 @@ int sd_event_source_get_enabled(sd_event_source *s, int *m) { int sd_event_source_set_enabled(sd_event_source *s, int m) { int r; - if (!s) - return -EINVAL; - if (m != SD_EVENT_OFF && m != SD_EVENT_ON && !SD_EVENT_ONESHOT) - return -EINVAL; + assert_return(s, -EINVAL); + assert_return(m == SD_EVENT_OFF || m == SD_EVENT_ON || m == SD_EVENT_ONESHOT, -EINVAL); assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE); - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(!event_pid_changed(s->event), -ECHILD); if (s->enabled == m) return 0; @@ -1150,8 +1126,12 @@ int sd_event_source_set_enabled(sd_event_source *s, int m) { break; - case SOURCE_DEFER: case SOURCE_QUIT: + s->enabled = m; + prioq_reshuffle(s->event->quit, s, &s->quit.prioq_index); + break; + + case SOURCE_DEFER: s->enabled = m; break; } @@ -1201,8 +1181,12 @@ int sd_event_source_set_enabled(sd_event_source *s, int m) { } break; - case SOURCE_DEFER: case SOURCE_QUIT: + s->enabled = m; + prioq_reshuffle(s->event->quit, s, &s->quit.prioq_index); + break; + + case SOURCE_DEFER: s->enabled = m; break; } @@ -1218,29 +1202,21 @@ int sd_event_source_set_enabled(sd_event_source *s, int m) { } int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) { - if (!s) - return -EINVAL; - if (!usec) - return -EINVAL; - if (s->type != SOURCE_REALTIME && s->type != SOURCE_MONOTONIC) - return -EDOM; - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(s, -EINVAL); + assert_return(usec, -EINVAL); + assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM); + assert_return(!event_pid_changed(s->event), -ECHILD); *usec = s->time.next; return 0; } int sd_event_source_set_time(sd_event_source *s, uint64_t usec) { - if (!s) - return -EINVAL; - if (usec == (uint64_t) -1) - return -EINVAL; - if (s->type != SOURCE_REALTIME && s->type != SOURCE_MONOTONIC) - return -EDOM; + assert_return(s, -EINVAL); + assert_return(usec != (uint64_t) -1, -EINVAL); + assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM); assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE); - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(!event_pid_changed(s->event), -ECHILD); if (s->time.next == usec) return 0; @@ -1258,14 +1234,22 @@ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) { return 0; } +int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) { + assert_return(s, -EINVAL); + assert_return(usec, -EINVAL); + assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM); + assert_return(!event_pid_changed(s->event), -ECHILD); + + *usec = s->time.accuracy; + return 0; +} + int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) { - if (!s) - return -EINVAL; - if (s->type != SOURCE_MONOTONIC && s->type != SOURCE_REALTIME) - return -EDOM; + assert_return(s, -EINVAL); + assert_return(usec != (uint64_t) -1, -EINVAL); + assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM); assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE); - if (event_pid_changed(s->event)) - return -ECHILD; + assert_return(!event_pid_changed(s->event), -ECHILD); if (usec == 0) usec = DEFAULT_ACCURACY_USEC; @@ -1283,17 +1267,13 @@ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) { return 0; } -int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) { - if (!s) - return -EINVAL; - if (!usec) - return -EINVAL; - if (s->type != SOURCE_MONOTONIC && s->type != SOURCE_REALTIME) - return -EDOM; - if (event_pid_changed(s->event)) - return -ECHILD; +int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) { + assert_return(s, -EINVAL); + assert_return(pid, -EINVAL); + assert_return(s->type == SOURCE_CHILD, -EDOM); + assert_return(!event_pid_changed(s->event), -ECHILD); - *usec = s->time.accuracy; + *pid = s->child.pid; return 0; } @@ -1456,9 +1436,7 @@ static int flush_timer(sd_event *e, int fd, uint32_t events) { assert(e); assert(fd >= 0); - - if (events != EPOLLIN) - return -EIO; + assert_return(events == EPOLLIN, -EIO); ss = read(fd, &x, sizeof(x)); if (ss < 0) { @@ -1474,7 +1452,12 @@ static int flush_timer(sd_event *e, int fd, uint32_t events) { return 0; } -static int process_timer(sd_event *e, usec_t n, Prioq *earliest, Prioq *latest) { +static int process_timer( + sd_event *e, + usec_t n, + Prioq *earliest, + Prioq *latest) { + sd_event_source *s; int r; @@ -1547,17 +1530,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); - if (events != EPOLLIN) - return -EIO; + 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)); @@ -1573,17 +1556,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); @@ -1717,7 +1699,6 @@ int sd_event_run(sd_event *e, uint64_t timeout) { struct epoll_event ev_queue[EPOLL_QUEUE_MAX]; sd_event_source *p; int r, i, m; - dual_timestamp n; assert_return(e, -EINVAL); assert_return(!event_pid_changed(e), -ECHILD); @@ -1755,7 +1736,7 @@ int sd_event_run(sd_event *e, uint64_t timeout) { goto finish; } - dual_timestamp_get(&n); + dual_timestamp_get(&e->timestamp); for (i = 0; i < m; i++) { @@ -1772,11 +1753,11 @@ int sd_event_run(sd_event *e, uint64_t timeout) { goto finish; } - r = process_timer(e, n.monotonic, e->monotonic_earliest, e->monotonic_latest); + r = process_timer(e, e->timestamp.monotonic, e->monotonic_earliest, e->monotonic_latest); if (r < 0) goto finish; - r = process_timer(e, n.realtime, e->realtime_earliest, e->realtime_latest); + r = process_timer(e, e->timestamp.realtime, e->realtime_earliest, e->realtime_latest); if (r < 0) goto finish; @@ -1845,3 +1826,23 @@ int sd_event_request_quit(sd_event *e) { e->quit_requested = true; return 0; } + +int sd_event_get_now_realtime(sd_event *e, uint64_t *usec) { + assert_return(e, -EINVAL); + assert_return(usec, -EINVAL); + assert_return(dual_timestamp_is_set(&e->timestamp), -ENODATA); + assert_return(!event_pid_changed(e), -ECHILD); + + *usec = e->timestamp.realtime; + return 0; +} + +int sd_event_get_now_monotonic(sd_event *e, uint64_t *usec) { + assert_return(e, -EINVAL); + assert_return(usec, -EINVAL); + assert_return(dual_timestamp_is_set(&e->timestamp), -ENODATA); + assert_return(!event_pid_changed(e), -ECHILD); + + *usec = e->timestamp.monotonic; + return 0; +}