From afc6adb5ec7e73bc13156c43f52fb015cd80cc68 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 11 Nov 2013 19:34:13 +0100 Subject: [PATCH] bus: introduce concept of a "default" event loop per-thread and make use of it everywhere Try to emphasize a bit that there should be a mapping between event loops and threads, hence introduce a logic that there's one "default" event loop for each thread, that can be queried via "sd_event_default()". --- src/hostname/hostnamed.c | 2 +- src/libsystemd-bus/libsystemd-bus.sym | 6 +++- src/libsystemd-bus/sd-event.c | 44 ++++++++++++++++++++++++++- src/libsystemd-bus/test-event.c | 2 +- src/locale/localed.c | 2 +- src/login/logind.c | 2 +- src/machine/machined.c | 2 +- src/network/networkd-manager.c | 2 +- src/socket-proxy/socket-proxyd.c | 2 +- src/systemd/sd-event.h | 6 +++- src/timedate/timedated.c | 2 +- 11 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 35dccf8cb..d2f0b022e 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -643,7 +643,7 @@ int main(int argc, char *argv[]) { goto finish; } - r = sd_event_new(&event); + r = sd_event_default(&event); if (r < 0) { log_error("Failed to allocate event loop: %s", strerror(-r)); goto finish; diff --git a/src/libsystemd-bus/libsystemd-bus.sym b/src/libsystemd-bus/libsystemd-bus.sym index 2c4f07d75..796a395a1 100644 --- a/src/libsystemd-bus/libsystemd-bus.sym +++ b/src/libsystemd-bus/libsystemd-bus.sym @@ -197,6 +197,8 @@ global: sd_memfd_set_size; /* sd-event functions */ + sd_event_default; + sd_event_new; sd_event_ref; sd_event_unref; @@ -213,15 +215,17 @@ global: sd_event_loop; sd_event_get_state; + sd_event_get_tid; sd_event_get_quit; sd_event_request_quit; sd_event_get_now_realtime; sd_event_get_now_monotonic; - sd_event_get; sd_event_source_ref; sd_event_source_unref; + sd_event_get; + sd_event_source_set_prepare; sd_event_source_get_pending; sd_event_source_get_priority; diff --git a/src/libsystemd-bus/sd-event.c b/src/libsystemd-bus/sd-event.c index 97e6db289..8025d24bb 100644 --- a/src/libsystemd-bus/sd-event.c +++ b/src/libsystemd-bus/sd-event.c @@ -23,12 +23,13 @@ #include #include +#include "sd-id128.h" #include "macro.h" #include "prioq.h" #include "hashmap.h" #include "util.h" #include "time-util.h" -#include "sd-id128.h" +#include "missing.h" #include "sd-event.h" @@ -138,6 +139,9 @@ struct sd_event { bool quit_requested:1; bool need_process_child:1; + + pid_t tid; + sd_event **default_event_ptr; }; static int pending_prioq_compare(const void *a, const void *b) { @@ -304,6 +308,9 @@ static int quit_prioq_compare(const void *a, const void *b) { static void event_free(sd_event *e) { assert(e); + if (e->default_event_ptr) + *(e->default_event_ptr) = NULL; + if (e->epoll_fd >= 0) close_nointr_nofail(e->epoll_fd); @@ -1869,3 +1876,38 @@ _public_ int sd_event_get_now_monotonic(sd_event *e, uint64_t *usec) { *usec = e->timestamp.monotonic; return 0; } + +_public_ int sd_event_default(sd_event **ret) { + + static __thread sd_event *default_event = NULL; + sd_event *e; + int r; + + if (!ret) + return !!default_event; + + if (default_event) { + *ret = sd_event_ref(default_event); + return 0; + } + + r = sd_event_new(&e); + if (r < 0) + return r; + + e->default_event_ptr = &default_event; + e->tid = gettid(); + default_event = e; + + *ret = e; + return 1; +} + +_public_ int sd_event_get_tid(sd_event *e, pid_t *tid) { + assert_return(e, -EINVAL); + assert_return(tid, -EINVAL); + assert_return(e->tid != 0, -ENXIO); + + *tid = e->tid; + return 0; +} diff --git a/src/libsystemd-bus/test-event.c b/src/libsystemd-bus/test-event.c index 65c1c296f..ba60a47a3 100644 --- a/src/libsystemd-bus/test-event.c +++ b/src/libsystemd-bus/test-event.c @@ -163,7 +163,7 @@ int main(int argc, char *argv[]) { assert_se(pipe(b) >= 0); assert_se(pipe(d) >= 0); - assert_se(sd_event_new(&e) >= 0); + assert_se(sd_event_default(&e) >= 0); got_a = false, got_b = false, got_c = false, got_d = 0; diff --git a/src/locale/localed.c b/src/locale/localed.c index 7e03d8257..32d52a90a 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -1115,7 +1115,7 @@ int main(int argc, char *argv[]) { goto finish; } - r = sd_event_new(&event); + r = sd_event_default(&event); if (r < 0) { log_error("Failed to allocate event loop: %s", strerror(-r)); goto finish; diff --git a/src/login/logind.c b/src/login/logind.c index c4227f16b..b54689e1d 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -90,7 +90,7 @@ Manager *manager_new(void) { return NULL; } - r = sd_event_new(&m->event); + r = sd_event_default(&m->event); if (r < 0) { manager_free(m); return NULL; diff --git a/src/machine/machined.c b/src/machine/machined.c index d6dd984e7..ee6a6d6ae 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -53,7 +53,7 @@ Manager *manager_new(void) { return NULL; } - r = sd_event_new(&m->event); + r = sd_event_default(&m->event); if (r < 0) { manager_free(m); return NULL; diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 6a57a8014..8378e92a8 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -31,7 +31,7 @@ int manager_new(Manager **ret) { if (!m) return -ENOMEM; - r = sd_event_new(&m->event); + r = sd_event_default(&m->event); if (r < 0) return r; diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c index 56e660de5..8cba8e067 100644 --- a/src/socket-proxy/socket-proxyd.c +++ b/src/socket-proxy/socket-proxyd.c @@ -626,7 +626,7 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; - r = sd_event_new(&event); + r = sd_event_default(&event); if (r < 0) { log_error("Failed to allocate event loop: %s", strerror(-r)); goto finish; diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h index 8262e139a..919b661d6 100644 --- a/src/systemd/sd-event.h +++ b/src/systemd/sd-event.h @@ -72,6 +72,8 @@ typedef int (*sd_defer_handler_t)(sd_event_source *s, void *userdata); typedef int (*sd_prepare_handler_t)(sd_event_source *s, void *userdata); typedef int (*sd_quit_handler_t)(sd_event_source *s, void *userdata); +int sd_event_default(sd_event **e); + int sd_event_new(sd_event **e); sd_event* sd_event_ref(sd_event *e); sd_event* sd_event_unref(sd_event *e); @@ -88,15 +90,17 @@ int sd_event_run(sd_event *e, uint64_t timeout); int sd_event_loop(sd_event *e); int sd_event_get_state(sd_event *e); +int sd_event_get_tid(sd_event *e, pid_t *tid); int sd_event_get_quit(sd_event *e); int sd_event_request_quit(sd_event *e); int sd_event_get_now_realtime(sd_event *e, uint64_t *usec); int sd_event_get_now_monotonic(sd_event *e, uint64_t *usec); -sd_event *sd_event_get(sd_event_source *s); sd_event_source* sd_event_source_ref(sd_event_source *s); sd_event_source* sd_event_source_unref(sd_event_source *s); +sd_event *sd_event_get(sd_event_source *s); + int sd_event_source_set_prepare(sd_event_source *s, sd_prepare_handler_t callback); int sd_event_source_get_pending(sd_event_source *s); int sd_event_source_get_priority(sd_event_source *s, int *priority); diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 163b2761a..8fb7f6e80 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -854,7 +854,7 @@ int main(int argc, char *argv[]) { goto finish; } - r = sd_event_new(&event); + r = sd_event_default(&event); if (r < 0) { log_error("Failed to allocate event loop: %s", strerror(-r)); goto finish; -- 2.30.2