chiark / gitweb /
sd-bus: add new sd_bus_slot_set_floating() call
authorLennart Poettering <lennart@poettering.net>
Wed, 30 May 2018 14:29:33 +0000 (16:29 +0200)
committerSven Eden <yamakuzure@gmx.net>
Fri, 24 Aug 2018 14:47:08 +0000 (16:47 +0200)
This new call allows explicit control of the "floating" state of a bus
slot object. This is useful for creating a bus slot object first,
retaining a reference to it, using it for making changes to the slot
object (for example, set a description) and then handing it over to
sd-bus for lifecycle management.

It's also useful to fix #8551.

src/libelogind/libelogind.sym
src/libelogind/sd-bus/bus-internal.h
src/libelogind/sd-bus/bus-slot.c
src/systemd/sd-bus.h

index 6e88f30d7bbcb00bf6061ee6e5067cb627f2a8f7..fd00c219862f1471e5a19c29cf1a9de19f0932e4 100644 (file)
@@ -567,4 +567,6 @@ global:
         sd_bus_open_with_description;
         sd_bus_open_user_with_description;
         sd_bus_open_system_with_description;
+        sd_bus_slot_get_floating;
+        sd_bus_slot_set_floating;
 } LIBSYSTEMD_238;
index 69a20773979a30eff0161fa5fe0d22866d44b868..8f3460ce23a5b9fd839287c9f7f7793d758e472a 100644 (file)
@@ -128,7 +128,15 @@ struct sd_bus_slot {
         sd_bus *bus;
         void *userdata;
         BusSlotType type:5;
+
+        /* Slots can be "floating" or not. If they are not floating (the usual case) then they reference the bus object
+         * they are associated with. This means the bus object stays allocated at least as long as there is a slot
+         * around associated with it. If it is floating, then the slot's lifecycle is bound to the lifecycle of the
+         * bus: it will be disconnected from the bus when the bus is destroyed, and it keeping the slot reffed hence
+         * won't mean the bus stays reffed too. Internally this means the reference direction is reversed: floating
+         * slots objects are referenced by the bus object, and not vice versa. */
         bool floating:1;
+
         bool match_added:1;
         char *description;
 
index 3745426c5c03d9fac353c8ad330c799e92a5c4fd..3e592e3a2fbb1d0b8e2a5ca0c92302cd41c97d04 100644 (file)
@@ -260,6 +260,37 @@ _public_ void* sd_bus_slot_get_current_userdata(sd_bus_slot *slot) {
         return slot->bus->current_userdata;
 }
 
+_public_ int sd_bus_slot_get_floating(sd_bus_slot *slot) {
+        assert_return(slot, -EINVAL);
+
+        return slot->floating;
+}
+
+_public_ int sd_bus_slot_set_floating(sd_bus_slot *slot, int b) {
+        assert_return(slot, -EINVAL);
+
+        if (slot->floating == !!b)
+                return 0;
+
+        if (!slot->bus) /* already disconnected slots can't be reconnected */
+                return -ESTALE;
+
+        slot->floating = b;
+
+        /* When a slot is "floating" then the bus references the slot. Otherwise the slot references the bus. Hence,
+         * when we move from one to the other, let's increase one reference and decrease the other. */
+
+        if (b) {
+                sd_bus_slot_ref(slot);
+                sd_bus_unref(slot->bus);
+        } else {
+                sd_bus_ref(slot->bus);
+                sd_bus_slot_unref(slot);
+        }
+
+        return 1;
+}
+
 _public_ int sd_bus_slot_set_description(sd_bus_slot *slot, const char *description) {
         assert_return(slot, -EINVAL);
 
index 9a6e862788c0fae48a9b9d2226eed2fc018ce5f4..cf38e4c6384824a2a5da3eb4f54da55ed962044a 100644 (file)
@@ -228,6 +228,8 @@ void *sd_bus_slot_get_userdata(sd_bus_slot *slot);
 void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata);
 int sd_bus_slot_set_description(sd_bus_slot *slot, const char *description);
 int sd_bus_slot_get_description(sd_bus_slot *slot, const char **description);
+int sd_bus_slot_get_floating(sd_bus_slot *slot);
+int sd_bus_slot_set_floating(sd_bus_slot *slot, int b);
 
 sd_bus_message* sd_bus_slot_get_current_message(sd_bus_slot *slot);
 sd_bus_message_handler_t sd_bus_slot_get_current_handler(sd_bus_slot *bus);