diff options
Diffstat (limited to '')
-rw-r--r-- | src/libsystemd/sd-bus/bus-socket.c | 22 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/sd-bus.c | 18 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/test-bus-watch-bind.c | 9 |
3 files changed, 31 insertions, 18 deletions
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index c94befe..e193e71 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -725,12 +725,12 @@ static int bus_socket_inotify_setup(sd_bus *b) { assert(b->sockaddr.sa.sa_family == AF_UNIX); assert(b->sockaddr.un.sun_path[0] != 0); - /* Sets up an inotify fd in case watch_bind is enabled: wait until the configured AF_UNIX file system socket - * appears before connecting to it. The implemented is pretty simplistic: we just subscribe to relevant changes - * to all prefix components of the path, and every time we get an event for that we try to reconnect again, - * without actually caring what precisely the event we got told us. If we still can't connect we re-subscribe - * to all relevant changes of anything in the path, so that our watches include any possibly newly created path - * components. */ + /* Sets up an inotify fd in case watch_bind is enabled: wait until the configured AF_UNIX file system + * socket appears before connecting to it. The implemented is pretty simplistic: we just subscribe to + * relevant changes to all components of the path, and every time we get an event for that we try to + * reconnect again, without actually caring what precisely the event we got told us. If we still + * can't connect we re-subscribe to all relevant changes of anything in the path, so that our watches + * include any possibly newly created path components. */ if (b->inotify_fd < 0) { b->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); @@ -749,17 +749,17 @@ static int bus_socket_inotify_setup(sd_bus *b) { if (r < 0) goto fail; - /* Watch all parent directories, and don't mind any prefix that doesn't exist yet. For the innermost directory - * that exists we want to know when files are created or moved into it. For all parents of it we just care if - * they are removed or renamed. */ + /* Watch all components of the path, and don't mind any prefix that doesn't exist yet. For the + * innermost directory that exists we want to know when files are created or moved into it. For all + * parents of it we just care if they are removed or renamed. */ if (!GREEDY_REALLOC(new_watches, n + 1)) { r = -ENOMEM; goto fail; } - /* Start with the top-level directory, which is a bit simpler than the rest, since it can't be a symlink, and - * always exists */ + /* Start with the top-level directory, which is a bit simpler than the rest, since it can't be a + * symlink, and always exists */ wd = inotify_add_watch(b->inotify_fd, "/", IN_CREATE|IN_MOVED_TO); if (wd < 0) { r = log_debug_errno(errno, "Failed to add inotify watch on /: %m"); diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 3c91dd3..37fb888 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -3040,7 +3040,7 @@ null_message: return r; } -static int bus_exit_now(sd_bus *bus) { +static int bus_exit_now(sd_bus *bus, sd_event *event) { assert(bus); /* Exit due to close, if this is requested. If this is bus object is attached to an event source, invokes @@ -3057,8 +3057,11 @@ static int bus_exit_now(sd_bus *bus) { log_debug("Bus connection disconnected, exiting."); - if (bus->event) - return sd_event_exit(bus->event, EXIT_FAILURE); + if (!event) + event = bus->event; + + if (event) + return sd_event_exit(event, EXIT_FAILURE); else exit(EXIT_FAILURE); @@ -3120,6 +3123,7 @@ static int process_closing_reply_callback(sd_bus *bus, struct reply_callback *c) static int process_closing(sd_bus *bus, sd_bus_message **ret) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + _cleanup_(sd_event_unrefp) sd_event *event = NULL; struct reply_callback *c; int r; @@ -3154,6 +3158,10 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) { if (r < 0) return r; + /* sd_bus_close() will deref the event and set bus->event to NULL. But in bus_exit_now() we use + * bus->event to decide whether to return from the event loop or exit(), but given it's always NULL + * at that point, it always exit(). Ref it here and pass it through further down to avoid that. */ + event = sd_event_ref(bus->event); sd_bus_close(bus); bus->current_message = m; @@ -3169,7 +3177,7 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) { /* Nothing else to do, exit now, if the condition holds */ bus->exit_triggered = true; - (void) bus_exit_now(bus); + (void) bus_exit_now(bus, event); if (ret) *ret = TAKE_PTR(m); @@ -4281,7 +4289,7 @@ _public_ int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b) { bus->exit_on_disconnect = b; /* If the exit condition was triggered already, exit immediately. */ - return bus_exit_now(bus); + return bus_exit_now(bus, /* event= */ NULL); } _public_ int sd_bus_get_exit_on_disconnect(sd_bus *bus) { diff --git a/src/libsystemd/sd-bus/test-bus-watch-bind.c b/src/libsystemd/sd-bus/test-bus-watch-bind.c index c577330..fae2a45 100644 --- a/src/libsystemd/sd-bus/test-bus-watch-bind.c +++ b/src/libsystemd/sd-bus/test-bus-watch-bind.c @@ -7,6 +7,7 @@ #include "sd-id128.h" #include "alloc-util.h" +#include "bus-internal.h" #include "fd-util.h" #include "fs-util.h" #include "mkdir.h" @@ -27,8 +28,11 @@ static int method_foobar(sd_bus_message *m, void *userdata, sd_bus_error *ret_er static int method_exit(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { log_info("Got Exit() call"); - assert_se(sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), 1) >= 0); - return sd_bus_reply_method_return(m, NULL); + + assert_se(sd_bus_reply_method_return(m, NULL) >= 0); + /* Simulate D-Bus going away to test the bus_exit_now() path with exit_on_disconnect set */ + bus_enter_closing(sd_bus_message_get_bus(m)); + return 0; } static const sd_bus_vtable vtable[] = { @@ -100,6 +104,7 @@ static void* thread_server(void *p) { log_debug("Accepted server connection"); assert_se(sd_bus_new(&bus) >= 0); + assert_se(sd_bus_set_exit_on_disconnect(bus, true) >= 0); assert_se(sd_bus_set_description(bus, "server") >= 0); assert_se(sd_bus_set_fd(bus, bus_fd, bus_fd) >= 0); assert_se(sd_bus_set_server(bus, true, id) >= 0); |