chiark / gitweb /
bus: make sure that we always keep a ref to the bus when we dispatch callbacks
authorLennart Poettering <lennart@poettering.net>
Mon, 14 Oct 2013 17:53:56 +0000 (19:53 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 14 Oct 2013 17:53:56 +0000 (19:53 +0200)
Otherwise the callback might unref the bus we are processing and destroy
the object while we are processing it.

src/libsystemd-bus/bus-internal.h
src/libsystemd-bus/bus-objects.c
src/libsystemd-bus/sd-bus.c

index 6499d6b013a76c5ee0f2b7434a0e8b26c4de298a..31e10b2c273e9d59eb4900ed49032a990486eb51 100644 (file)
@@ -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), '/'))
         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)
index cd56d13d6bf4575d37e2944f17eb567bc8285b09..9142fab37a9abcde24bb5dbb686d49f23b2a046b 100644 (file)
@@ -1843,6 +1843,7 @@ int sd_bus_emit_properties_changed_strv(
                 const char *interface,
                 char **names) {
 
                 const char *interface,
                 char **names) {
 
+        BUS_DONT_DESTROY(bus);
         char *prefix;
         int r;
 
         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) {
 }
 
 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;
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         char **i;
         int r;
index 44c13d36a4fce69f09f3f440d5b8897108f8b3d9..ee5f3955695fb618ba50ef964eabf8d72ccb747a 100644 (file)
@@ -1870,6 +1870,7 @@ null_message:
 }
 
 int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
 }
 
 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
         int r;
 
         /* Returns 0 when we didn't do anything. This should cause the