X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-event%2Fsd-event.c;h=db7643347f3f45c9f2e8584548a43d48c0c93088;hb=bdd13f6be4b588568683a1ab54f421fc6a636dbb;hp=f33a9ecf9ac8dee1b8d6ba4f74c68429d120ad9e;hpb=607553f9306286fdccf0b356bc3d1087adfe21c4;p=elogind.git diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index f33a9ecf9..db7643347 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -32,6 +32,7 @@ #include "util.h" #include "time-util.h" #include "missing.h" +#include "set.h" #include "sd-event.h" @@ -45,6 +46,7 @@ typedef enum EventSourceType { SOURCE_SIGNAL, SOURCE_CHILD, SOURCE_DEFER, + SOURCE_POST, SOURCE_EXIT, SOURCE_WATCHDOG } EventSourceType; @@ -95,6 +97,9 @@ struct sd_event_source { struct { sd_event_handler_t callback; } defer; + struct { + sd_event_handler_t callback; + } post; struct { sd_event_handler_t callback; unsigned prioq_index; @@ -134,6 +139,8 @@ struct sd_event { Hashmap *child_sources; unsigned n_enabled_child_sources; + Set *post_sources; + Prioq *exit; pid_t original_pid; @@ -350,6 +357,7 @@ static void event_free(sd_event *e) { free(e->signal_sources); hashmap_free(e->child_sources); + set_free(e->post_sources); free(e); } @@ -524,6 +532,10 @@ static void source_free(sd_event_source *s) { /* nothing */ break; + case SOURCE_POST: + set_remove(s->event->post_sources, s); + break; + case SOURCE_EXIT: prioq_remove(s->event->exit, s, &s->exit.prioq_index); break; @@ -599,11 +611,11 @@ static sd_event_source *source_new(sd_event *e, EventSourceType type) { _public_ int sd_event_add_io( sd_event *e, + sd_event_source **ret, int fd, uint32_t events, sd_event_io_handler_t callback, - void *userdata, - sd_event_source **ret) { + void *userdata) { sd_event_source *s; int r; @@ -642,9 +654,9 @@ static int event_setup_timer_fd( int *timer_fd, clockid_t id) { + sd_id128_t bootid = {}; struct epoll_event ev = {}; int r, fd; - sd_id128_t bootid; assert(e); assert(timer_fd); @@ -683,6 +695,7 @@ static int event_setup_timer_fd( static int event_add_time_internal( sd_event *e, + sd_event_source **ret, EventSourceType type, int *timer_fd, clockid_t id, @@ -691,8 +704,7 @@ static int event_add_time_internal( uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, - void *userdata, - sd_event_source **ret) { + void *userdata) { sd_event_source *s; int r; @@ -755,23 +767,23 @@ fail: } _public_ int sd_event_add_monotonic(sd_event *e, + sd_event_source **ret, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, - void *userdata, - sd_event_source **ret) { + void *userdata) { - return event_add_time_internal(e, SOURCE_MONOTONIC, &e->monotonic_fd, CLOCK_MONOTONIC, &e->monotonic_earliest, &e->monotonic_latest, usec, accuracy, callback, userdata, ret); + return event_add_time_internal(e, ret, SOURCE_MONOTONIC, &e->monotonic_fd, CLOCK_MONOTONIC, &e->monotonic_earliest, &e->monotonic_latest, usec, accuracy, callback, userdata); } _public_ int sd_event_add_realtime(sd_event *e, + sd_event_source **ret, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, - void *userdata, - sd_event_source **ret) { + void *userdata) { - return event_add_time_internal(e, SOURCE_REALTIME, &e->realtime_fd, CLOCK_REALTIME, &e->realtime_earliest, &e->monotonic_latest, usec, accuracy, callback, userdata, ret); + return event_add_time_internal(e, ret, SOURCE_REALTIME, &e->realtime_fd, CLOCK_REALTIME, &e->realtime_earliest, &e->realtime_latest, usec, accuracy, callback, userdata); } static int event_update_signal_fd(sd_event *e) { @@ -808,10 +820,10 @@ static int event_update_signal_fd(sd_event *e) { _public_ int sd_event_add_signal( sd_event *e, + sd_event_source **ret, int sig, sd_event_signal_handler_t callback, - void *userdata, - sd_event_source **ret) { + void *userdata) { sd_event_source *s; sigset_t ss; @@ -865,11 +877,11 @@ _public_ int sd_event_add_signal( _public_ int sd_event_add_child( sd_event *e, + sd_event_source **ret, pid_t pid, int options, sd_event_child_handler_t callback, - void *userdata, - sd_event_source **ret) { + void *userdata) { sd_event_source *s; int r; @@ -926,9 +938,9 @@ _public_ int sd_event_add_child( _public_ int sd_event_add_defer( sd_event *e, + sd_event_source **ret, sd_event_handler_t callback, - void *userdata, - sd_event_source **ret) { + void *userdata) { sd_event_source *s; int r; @@ -957,11 +969,48 @@ _public_ int sd_event_add_defer( return 0; } +_public_ int sd_event_add_post( + sd_event *e, + sd_event_source **ret, + sd_event_handler_t callback, + void *userdata) { + + 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); + + r = set_ensure_allocated(&e->post_sources, trivial_hash_func, trivial_compare_func); + if (r < 0) + return r; + + s = source_new(e, SOURCE_POST); + if (!s) + return -ENOMEM; + + s->post.callback = callback; + s->userdata = userdata; + s->enabled = SD_EVENT_ON; + + r = set_put(e->post_sources, s); + if (r < 0) { + source_free(s); + return r; + } + + *ret = s; + return 0; +} + _public_ int sd_event_add_exit( sd_event *e, + sd_event_source **ret, sd_event_handler_t callback, - void *userdata, - sd_event_source **ret) { + void *userdata) { sd_event_source *s; int r; @@ -1246,6 +1295,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { break; case SOURCE_DEFER: + case SOURCE_POST: s->enabled = m; break; @@ -1286,8 +1336,6 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { break; case SOURCE_CHILD: - s->enabled = m; - if (s->enabled == SD_EVENT_OFF) { s->event->n_enabled_child_sources++; @@ -1296,6 +1344,8 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { event_update_signal_fd(s->event); } } + + s->enabled = m; break; case SOURCE_EXIT: @@ -1304,6 +1354,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { break; case SOURCE_DEFER: + case SOURCE_POST: s->enabled = m; break; @@ -1763,8 +1814,6 @@ static int process_signal(sd_event *e, uint32_t events) { if (r < 0) return r; } - - return 0; } static int source_dispatch(sd_event_source *s) { @@ -1779,6 +1828,23 @@ static int source_dispatch(sd_event_source *s) { return r; } + if (s->type != SOURCE_POST) { + sd_event_source *z; + Iterator i; + + /* If we execute a non-post source, let's mark all + * post sources as pending */ + + SET_FOREACH(z, s->event->post_sources, i) { + if (z->enabled == SD_EVENT_OFF) + continue; + + r = source_set_pending(z, true); + if (r < 0) + return r; + } + } + if (s->enabled == SD_EVENT_ONESHOT) { r = sd_event_source_set_enabled(s, SD_EVENT_OFF); if (r < 0) @@ -1825,6 +1891,10 @@ static int source_dispatch(sd_event_source *s) { r = s->defer.callback(s, s->userdata); break; + case SOURCE_POST: + r = s->post.callback(s, s->userdata); + break; + case SOURCE_EXIT: r = s->exit.callback(s, s->userdata); break; @@ -2126,7 +2196,7 @@ _public_ int sd_event_get_now_monotonic(sd_event *e, uint64_t *usec) { _public_ int sd_event_default(sd_event **ret) { static thread_local sd_event *default_event = NULL; - sd_event *e; + sd_event *e = NULL; int r; if (!ret)