Handle return slot with kdbus async calls
authorMaciej Slodczyk <m.slodczyk2@partner.samsung.com>
Fri, 21 Feb 2020 17:02:26 +0000 (18:02 +0100)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Thu, 25 Jan 2024 12:22:10 +0000 (13:22 +0100)
Signed-off-by: Maciej Slodczyk <m.slodczyk2@partner.samsung.com>
src/libsystemd/sd-bus/bus-control-kernel.c
src/libsystemd/sd-bus/bus-internal.h
src/libsystemd/sd-bus/bus-slot.c

index b09f5b7..348051f 100644 (file)
@@ -33,6 +33,7 @@
 #include "bus-internal.h"
 #include "bus-message.h"
 #include "bus-util.h"
+#include "bus-slot.h"
 #include "capability-util.h"
 #include "process-util.h"
 #include "stdio-util.h"
@@ -75,11 +76,14 @@ int bus_request_name_kernel(sd_bus *bus, const char *name, uint64_t flags) {
 struct kernel_async_call_data {
        sd_bus *bus;
        sd_bus_message_handler_t callback;
+    sd_bus_slot *slot;
        void *userdata;
        int retval;
        sd_event_source *event;
 };
 
+
+
 static int bus_name_kernel_async_callback(
                sd_event_source *s,
                uint64_t usec,
@@ -112,6 +116,11 @@ static int bus_name_kernel_async_callback(
        if (k->callback)
                ret = k->callback(m, k->userdata, &e);
 
+    if (k->slot) {
+        sd_bus_slot_set_userdata(k->slot, NULL);
+        sd_bus_slot_set_destroy_callback(k->slot, NULL);
+    }
+
        sd_bus_error_free(&e);
        sd_event_source_unref(k->event);
        sd_bus_message_unref(m);
@@ -120,6 +129,20 @@ static int bus_name_kernel_async_callback(
        return ret;
 }
 
+static void kdbus_async_slot_destroy(void *data)
+{
+    struct kernel_async_call_data *k = (struct kernel_async_call_data *)data;
+    if (!k)
+        return;
+
+    /* make sure that the callback will not be called;
+    * resources will be released on timeout anyway */
+    k->callback = NULL;
+
+    /* it's gone so don't use it on event execution */
+    k->slot = NULL;
+}
+
 int bus_request_name_kernel_async(sd_bus *bus,
                sd_bus_slot **ret_slot,
                const char *name,
@@ -132,18 +155,31 @@ int bus_request_name_kernel_async(sd_bus *bus,
        if (!bus->event)
                return 0;
 
-       ret     = bus_request_name_kernel(bus, name, flags);
+    if (NULL != ret_slot) {
+        *ret_slot = bus_slot_allocate(bus, false, BUS_KDBUS_CALLBACK, 0, NULL);
+        if (!(*ret_slot))
+            return -ENOMEM;
+    }
+
+    ret = bus_request_name_kernel(bus, name, flags);
 
        k = (struct kernel_async_call_data *)calloc(1, sizeof *k);
        k->bus = bus;
        k->callback = callback;
        k->userdata = userdata;
        k->retval = ret;
+    k->slot = NULL;
 
-       /*TODO*/
-       *ret_slot = NULL;
+    ret = sd_event_add_time(bus->event, &k->event, CLOCK_MONOTONIC, 0, 1, bus_name_kernel_async_callback, (void *)k);
 
-       return sd_event_add_time(bus->event, &k->event, CLOCK_MONOTONIC, 0, 1, bus_name_kernel_async_callback, (void *)k);
+    if (NULL != ret_slot) {
+        k->slot = *ret_slot;
+
+        sd_bus_slot_set_userdata(*ret_slot, k);
+        sd_bus_slot_set_destroy_callback(*ret_slot, kdbus_async_slot_destroy);
+    }
+
+    return ret;
 }
 
 int bus_release_name_kernel(sd_bus *bus, const char *name) {
@@ -185,6 +221,12 @@ int bus_release_name_kernel_async(
        if (!bus->event)
                return 0;
 
+    if (NULL != ret_slot) {
+        *ret_slot = bus_slot_allocate(bus, false, BUS_KDBUS_CALLBACK, 0, NULL);
+        if (!(*ret_slot))
+            return -ENOMEM;
+    }
+
        ret     = bus_release_name_kernel(bus, name);
 
        k = (struct kernel_async_call_data *)calloc(1, sizeof *k);
@@ -192,11 +234,18 @@ int bus_release_name_kernel_async(
        k->callback = callback;
        k->userdata = userdata;
        k->retval = ret;
+    k->slot = NULL;
+
+    ret = sd_event_add_time(bus->event, &k->event, CLOCK_MONOTONIC, 0, 1, bus_name_kernel_async_callback, (void *)k);
 
-       /*TODO*/
-       *ret_slot = NULL;
+    if (NULL != ret_slot) {
+        k->slot = *ret_slot;
 
-       return sd_event_add_time(bus->event, &k->event, CLOCK_MONOTONIC, 0, 1, bus_name_kernel_async_callback, (void *)k);
+        sd_bus_slot_set_userdata(*ret_slot, k);
+        sd_bus_slot_set_destroy_callback(*ret_slot, kdbus_async_slot_destroy);
+    }
+
+    return ret;
 }
 
 
@@ -1152,6 +1201,11 @@ static int bus_match_kernel_async_callback(
        if (k->callback)
                ret = k->callback(m, k->userdata, &e);
 
+    if (k->slot) {
+        sd_bus_slot_set_userdata(k->slot, NULL);
+        sd_bus_slot_set_destroy_callback(k->slot, NULL);
+    }
+
        sd_bus_error_free(&e);
        sd_event_source_unref(k->event);
        sd_bus_message_unref(m);
@@ -1173,6 +1227,12 @@ int bus_add_match_internal_kernel_async(
        int ret;
        struct kernel_async_call_data *k;
 
+    if (NULL != ret_slot) {
+        *ret_slot = bus_slot_allocate(bus, false, BUS_KDBUS_CALLBACK, 0, NULL);
+        if (!(*ret_slot))
+            return -ENOMEM;
+    }
+
     ret = bus_add_match_internal_kernel(bus, components, n_components, cookie);
 
        k = (struct kernel_async_call_data *)calloc(1, sizeof *k);
@@ -1180,12 +1240,18 @@ int bus_add_match_internal_kernel_async(
        k->callback = callback;
        k->userdata = userdata;
        k->retval = ret;
+    k->slot = NULL;
+
+    ret = sd_event_add_time(bus->event, &k->event, CLOCK_MONOTONIC, 0, 1, bus_match_kernel_async_callback, (void *)k);
 
-       /*TODO*/
-       *ret_slot = NULL;
+    if (NULL != ret_slot) {
+        k->slot = *ret_slot;
 
-       return sd_event_add_time(bus->event, &k->event, CLOCK_MONOTONIC, 0, 1, bus_match_kernel_async_callback, (void *)k);
+        sd_bus_slot_set_userdata(*ret_slot, k);
+        sd_bus_slot_set_destroy_callback(*ret_slot, kdbus_async_slot_destroy);
+    }
 
+    return ret;
 }
 
 int bus_remove_match_internal_kernel(
index 721d6c7..85f4e9b 100644 (file)
@@ -135,6 +135,7 @@ typedef enum BusSlotType {
         BUS_NODE_ENUMERATOR,
         BUS_NODE_VTABLE,
         BUS_NODE_OBJECT_MANAGER,
+        BUS_KDBUS_CALLBACK,
         _BUS_SLOT_INVALID = -1,
 } BusSlotType;
 
index 7fd5368..28c6b1d 100644 (file)
@@ -76,6 +76,8 @@ void bus_slot_disconnect(sd_bus_slot *slot) {
 
         switch (slot->type) {
 
+        case BUS_KDBUS_CALLBACK:
+                break;
         case BUS_REPLY_CALLBACK:
 
                 if (slot->reply_callback.cookie != 0)