#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"
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,
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);
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,
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) {
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);
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;
}
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);
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);
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(