From 24dc1ec35520acf5407e307bcfee2ab7f8404356 Mon Sep 17 00:00:00 2001 From: Maciej Slodczyk Date: Fri, 21 Feb 2020 18:02:26 +0100 Subject: [PATCH] Handle return slot with kdbus async calls Signed-off-by: Maciej Slodczyk --- src/libsystemd/sd-bus/bus-control-kernel.c | 86 ++++++++++++++++++++++++++---- src/libsystemd/sd-bus/bus-internal.h | 1 + src/libsystemd/sd-bus/bus-slot.c | 2 + 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/src/libsystemd/sd-bus/bus-control-kernel.c b/src/libsystemd/sd-bus/bus-control-kernel.c index b09f5b7..348051f 100644 --- a/src/libsystemd/sd-bus/bus-control-kernel.c +++ b/src/libsystemd/sd-bus/bus-control-kernel.c @@ -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( diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h index 721d6c7..85f4e9b 100644 --- a/src/libsystemd/sd-bus/bus-internal.h +++ b/src/libsystemd/sd-bus/bus-internal.h @@ -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; diff --git a/src/libsystemd/sd-bus/bus-slot.c b/src/libsystemd/sd-bus/bus-slot.c index 7fd5368..28c6b1d 100644 --- a/src/libsystemd/sd-bus/bus-slot.c +++ b/src/libsystemd/sd-bus/bus-slot.c @@ -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) -- 2.7.4