summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-06-06 11:07:02 +0200
committerSven Eden <yamakuzure@gmx.net>2018-08-24 16:47:08 +0200
commit1aa207c0a5005a80bf30924c2325f901d7f7f80c (patch)
tree84c65d2062737310d6b8f2b8bffe57031e85ffe2
parentf44b01c3269d71cff4566a894fe48c35ca77e11c (diff)
bus: optionally call a callbacks for cleanup
This adds a function sd_bus_slot_set_destroy_callback() to set a function which can free userdata or perform other cleanups. sd_bus_slot_get_destory_callback() queries the callback, and is included for completeness. Without something like this, for floating asynchronous callbacks, which might be called or not, depending on the sequence of events, it's hard to perform resource cleanup. The alternative would be to always perform the cleanup from the caller too, but that requires more coordination and keeping of some shared state. It's nicer to keep the cleanup contained between the callback and the function that requests the callback.
-rw-r--r--man/rules/meson.build4
-rw-r--r--man/sd_bus_slot_set_destroy_callback.xml105
-rw-r--r--man/sd_bus_slot_set_floating.xml9
-rw-r--r--src/libelogind/libelogind.sym2
-rw-r--r--src/libelogind/sd-bus/bus-internal.h1
-rw-r--r--src/libelogind/sd-bus/bus-slot.c20
-rw-r--r--src/systemd/sd-bus.h3
7 files changed, 143 insertions, 1 deletions
diff --git a/man/rules/meson.build b/man/rules/meson.build
index 12a927caa..e9b045207 100644
--- a/man/rules/meson.build
+++ b/man/rules/meson.build
@@ -231,6 +231,10 @@ manpages = [
['sd_bus_set_connected_signal', '3', ['sd_bus_get_connected_signal'], ''],
['sd_bus_set_sender', '3', ['sd_bus_get_sender'], ''],
['sd_bus_set_watch_bind', '3', ['sd_bus_get_watch_bind'], ''],
+ ['sd_bus_slot_set_destroy_callback',
+ '3',
+ ['sd_bus_slot_get_destroy_callback'],
+ ''],
['sd_bus_slot_set_floating', '3', ['sd_bus_slot_get_floating'], ''],
['sd_bus_track_add_name',
'3',
diff --git a/man/sd_bus_slot_set_destroy_callback.xml b/man/sd_bus_slot_set_destroy_callback.xml
new file mode 100644
index 000000000..36d0abd63
--- /dev/null
+++ b/man/sd_bus_slot_set_destroy_callback.xml
@@ -0,0 +1,105 @@
+<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!-- SPDX-License-Identifier: LGPL-2.1+ -->
+
+<refentry id="sd_bus_slot_set_destroy_callback"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <refentryinfo>
+ <title>sd_bus_slot_set_destroy_callback</title>
+ <productname>elogind</productname>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>sd_bus_slot_set_destroy_callback</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sd_bus_slot_set_destroy_callback</refname>
+ <refname>sd_bus_slot_get_destroy_callback</refname>
+
+ <refpurpose>Define the callback function for resource cleanup.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;elogind/sd-bus.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>typedef int (*<function>sd_bus_destroy_t</function>)</funcdef>
+ <paramdef>void *<parameter>userdata</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_bus_slot_set_destroy_callback</function></funcdef>
+ <paramdef>sd_bus_slot *<parameter>slot</parameter></paramdef>
+ <paramdef>sd_bus_destroy_t <parameter>callback</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_bus_slot_get_destroy_callback</function></funcdef>
+ <paramdef>sd_bus_slot *<parameter>slot</parameter></paramdef>
+ <paramdef>sd_bus_destroy_t *<parameter>callback</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><function>sd_bus_slot_set_destroy_callback()</function> sets
+ <parameter>callback</parameter> as the callback function to be called right before the bus slot
+ object <parameter>slot</parameter> is deallocated. The <parameter>userdata</parameter> pointer
+ from the slot object will be passed as the <parameter>userdata</parameter> parameter. This
+ pointer can be set specified as an argument to the constuctor functions, see
+ <citerefentry><refentrytitle>sd_bus_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ or directly, see
+ <citerefentry><refentrytitle>sd_bus_set_userdata</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ This callback function is called even if <parameter>userdata</parameter> is
+ <constant>NULL</constant>.</para>
+
+ <para><function>sd_bus_slot_get_destroy_callback()</function> returns the current callback
+ for <parameter>slot</parameter> in the <parameter>callback</parameter> parameter.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>On success, <function>sd_bus_slot_set_destroy_callback()</function> returns 0 or a
+ positive integer. On failure, it returns a negative errno-style error code.</para>
+
+ <para><function>sd_bus_slot_get_destroy_callback()</function> returns 1 if the destroy callback
+ function is set, 0 if not. On failure, it returns a negative errno-style error code.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Errors</title>
+
+ <para>Returned errors may indicate the following problems:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><constant>-EINVAL</constant></term>
+
+ <listitem><para>The <parameter>slot</parameter> parameter is <constant>NULL</constant>.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <xi:include href="libelogind-pkgconfig.xml" />
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <citerefentry><refentrytitle>elogind</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_bus_slot_set_floating</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/sd_bus_slot_set_floating.xml b/man/sd_bus_slot_set_floating.xml
index ef370a671..ae733e95d 100644
--- a/man/sd_bus_slot_set_floating.xml
+++ b/man/sd_bus_slot_set_floating.xml
@@ -29,7 +29,7 @@
<funcprototype>
<funcdef>int <function>sd_bus_slot_set_floating</function></funcdef>
- <paramdef>sd_bus_slot *<parameter>bus</parameter></paramdef>
+ <paramdef>sd_bus_slot *<parameter>slot</parameter></paramdef>
<paramdef>int <parameter>b</parameter></paramdef>
</funcprototype>
@@ -82,6 +82,12 @@
<variablelist>
<varlistentry>
+ <term><constant>-EINVAL</constant></term>
+
+ <listitem><para>The <parameter>slot</parameter> parameter is <constant>NULL</constant>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><constant>-ECHILD</constant></term>
<listitem><para>The bus connection has been created in a different process.</para></listitem>
@@ -104,6 +110,7 @@
<para>
<citerefentry><refentrytitle>elogind</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_bus_slot_set_destroy_callback</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/src/libelogind/libelogind.sym b/src/libelogind/libelogind.sym
index 9dd25c738..916dfcf83 100644
--- a/src/libelogind/libelogind.sym
+++ b/src/libelogind/libelogind.sym
@@ -569,6 +569,8 @@ global:
sd_bus_open_system_with_description;
sd_bus_slot_get_floating;
sd_bus_slot_set_floating;
+ sd_bus_slot_get_destroy_callback;
+ sd_bus_slot_set_destroy_callback;
sd_event_add_inotify;
sd_event_source_get_inotify_mask;
} LIBSYSTEMD_238;
diff --git a/src/libelogind/sd-bus/bus-internal.h b/src/libelogind/sd-bus/bus-internal.h
index 8f3460ce2..cfe299e01 100644
--- a/src/libelogind/sd-bus/bus-internal.h
+++ b/src/libelogind/sd-bus/bus-internal.h
@@ -127,6 +127,7 @@ struct sd_bus_slot {
unsigned n_ref;
sd_bus *bus;
void *userdata;
+ sd_bus_destroy_t destroy_callback;
BusSlotType type:5;
/* Slots can be "floating" or not. If they are not floating (the usual case) then they reference the bus object
diff --git a/src/libelogind/sd-bus/bus-slot.c b/src/libelogind/sd-bus/bus-slot.c
index 34cfdd29e..db9af9a97 100644
--- a/src/libelogind/sd-bus/bus-slot.c
+++ b/src/libelogind/sd-bus/bus-slot.c
@@ -203,6 +203,10 @@ _public_ sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) {
}
bus_slot_disconnect(slot);
+
+ if (slot->destroy_callback)
+ slot->destroy_callback(slot->userdata);
+
free(slot->description);
return mfree(slot);
}
@@ -230,6 +234,22 @@ _public_ void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata) {
return ret;
}
+_public_ int sd_bus_slot_set_destroy_callback(sd_bus_slot *slot, sd_bus_destroy_t callback) {
+ assert_return(slot, -EINVAL);
+
+ slot->destroy_callback = callback;
+ return 0;
+}
+
+_public_ int sd_bus_slot_get_destroy_callback(sd_bus_slot *slot, sd_bus_destroy_t *callback) {
+ assert_return(slot, -EINVAL);
+
+ if (callback)
+ *callback = slot->destroy_callback;
+
+ return !!slot->destroy_callback;
+}
+
_public_ sd_bus_message *sd_bus_slot_get_current_message(sd_bus_slot *slot) {
assert_return(slot, NULL);
assert_return(slot->type >= 0, NULL);
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index cf38e4c63..6a9e361fe 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -111,6 +111,7 @@ typedef int (*sd_bus_property_set_t) (sd_bus *bus, const char *path, const char
typedef int (*sd_bus_object_find_t) (sd_bus *bus, const char *path, const char *interface, void *userdata, void **ret_found, sd_bus_error *ret_error);
typedef int (*sd_bus_node_enumerator_t) (sd_bus *bus, const char *prefix, void *userdata, char ***ret_nodes, sd_bus_error *ret_error);
typedef int (*sd_bus_track_handler_t) (sd_bus_track *track, void *userdata);
+typedef void (*sd_bus_destroy_t)(void *userdata);
#include "sd-bus-protocol.h"
#include "sd-bus-vtable.h"
@@ -230,6 +231,8 @@ 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);
+int sd_bus_slot_set_destroy_callback(sd_bus_slot *s, sd_bus_destroy_t callback);
+int sd_bus_slot_get_destroy_callback(sd_bus_slot *s, sd_bus_destroy_t *callback);
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);