diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-10-14 19:53:56 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-10-14 19:53:56 +0200 |
commit | 8ce2afd6347dcf01e33fe1ff257e2b0fffa8edfe (patch) | |
tree | f90e1b693239377c283be59ead467993887c5ec2 | |
parent | d68888227d2e1093f8e18753ba2e10a1cab7c6ad (diff) |
bus: make sure that we always keep a ref to the bus when we dispatch callbacks
Otherwise the callback might unref the bus we are processing and destroy
the object while we are processing it.
-rw-r--r-- | src/libsystemd-bus/bus-internal.h | 6 | ||||
-rw-r--r-- | src/libsystemd-bus/bus-objects.c | 3 | ||||
-rw-r--r-- | src/libsystemd-bus/sd-bus.c | 1 |
3 files changed, 10 insertions, 0 deletions
diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h index 6499d6b013..31e10b2c27 100644 --- a/src/libsystemd-bus/bus-internal.h +++ b/src/libsystemd-bus/bus-internal.h @@ -294,3 +294,9 @@ bool bus_pid_changed(sd_bus *bus); for (char *_slash = ({ strcpy((prefix), (path)); streq((prefix), "/") ? NULL : strrchr((prefix), '/'); }) ; \ _slash && !(_slash[(_slash) == (prefix)] = 0); \ _slash = streq((prefix), "/") ? NULL : strrchr((prefix), '/')) + +/* If we are invoking callbacks of a bus object, ensure unreffing the + * bus from the callback doesn't destroy the object we are working + * on */ +#define BUS_DONT_DESTROY(bus) \ + _cleanup_bus_unref_ sd_bus *_dont_destroy_##bus = sd_bus_ref(bus) diff --git a/src/libsystemd-bus/bus-objects.c b/src/libsystemd-bus/bus-objects.c index cd56d13d6b..9142fab37a 100644 --- a/src/libsystemd-bus/bus-objects.c +++ b/src/libsystemd-bus/bus-objects.c @@ -1843,6 +1843,7 @@ int sd_bus_emit_properties_changed_strv( const char *interface, char **names) { + BUS_DONT_DESTROY(bus); char *prefix; int r; @@ -1987,6 +1988,8 @@ static int interfaces_added_append_one( } int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, char **interfaces) { + BUS_DONT_DESTROY(bus); + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; char **i; int r; diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 44c13d36a4..ee5f395569 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -1870,6 +1870,7 @@ null_message: } int sd_bus_process(sd_bus *bus, sd_bus_message **ret) { + BUS_DONT_DESTROY(bus); int r; /* Returns 0 when we didn't do anything. This should cause the |