summaryrefslogtreecommitdiff
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
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.
-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