summaryrefslogtreecommitdiff
path: root/src/libsystemd-bus
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-10-14 19:53:56 +0200
committerLennart Poettering <lennart@poettering.net>2013-10-14 19:53:56 +0200
commit8ce2afd6347dcf01e33fe1ff257e2b0fffa8edfe (patch)
treef90e1b693239377c283be59ead467993887c5ec2 /src/libsystemd-bus
parentd68888227d2e1093f8e18753ba2e10a1cab7c6ad (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.
Diffstat (limited to 'src/libsystemd-bus')
-rw-r--r--src/libsystemd-bus/bus-internal.h6
-rw-r--r--src/libsystemd-bus/bus-objects.c3
-rw-r--r--src/libsystemd-bus/sd-bus.c1
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