summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libelogind/libelogind.sym2
-rw-r--r--src/libelogind/sd-bus/bus-internal.h8
-rw-r--r--src/libelogind/sd-bus/bus-slot.c31
-rw-r--r--src/systemd/sd-bus.h2
4 files changed, 43 insertions, 0 deletions
diff --git a/src/libelogind/libelogind.sym b/src/libelogind/libelogind.sym
index 6e88f30d7..fd00c2198 100644
--- a/src/libelogind/libelogind.sym
+++ b/src/libelogind/libelogind.sym
@@ -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;
diff --git a/src/libelogind/sd-bus/bus-internal.h b/src/libelogind/sd-bus/bus-internal.h
index 69a207739..8f3460ce2 100644
--- a/src/libelogind/sd-bus/bus-internal.h
+++ b/src/libelogind/sd-bus/bus-internal.h
@@ -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;
diff --git a/src/libelogind/sd-bus/bus-slot.c b/src/libelogind/sd-bus/bus-slot.c
index 3745426c5..3e592e3a2 100644
--- a/src/libelogind/sd-bus/bus-slot.c
+++ b/src/libelogind/sd-bus/bus-slot.c
@@ -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);
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 9a6e86278..cf38e4c63 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -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);