chiark / gitweb /
bus: optionally call a callbacks for cleanup
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 6 Jun 2018 09:07:02 +0000 (11:07 +0200)
committerSven Eden <yamakuzure@gmx.net>
Fri, 24 Aug 2018 14:47:08 +0000 (16:47 +0200)
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.

man/rules/meson.build
man/sd_bus_slot_set_destroy_callback.xml [new file with mode: 0644]
man/sd_bus_slot_set_floating.xml
src/libelogind/libelogind.sym
src/libelogind/sd-bus/bus-internal.h
src/libelogind/sd-bus/bus-slot.c
src/systemd/sd-bus.h

index 12a927caa0971a64c03100fbf32a1c5da0a6e997..e9b04520777ae70f71abaab3b91b06afc8c3c9f2 100644 (file)
@@ -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 (file)
index 0000000..36d0abd
--- /dev/null
@@ -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>
index ef370a671f0a8a401981290d14af123bd3b25aaf..ae733e95de13325199fa32593719476b3c178504 100644 (file)
@@ -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>
 
     <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>
+
       <varlistentry>
         <term><constant>-ECHILD</constant></term>
 
     <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>
index 9dd25c73802326527263bc7d56c8e75216e8a8e7..916dfcf8379a91ab1c82c4c99356c8007351ab60 100644 (file)
@@ -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;
index 8f3460ce23a5b9fd839287c9f7f7793d758e472a..cfe299e01840f3b186c57dd62019cd92face0dd0 100644 (file)
@@ -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
index 34cfdd29e9508aba8580b1bbe958bbc33bffc7ff..db9af9a97e7c58013426f26f48905599227f0058 100644 (file)
@@ -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);
index cf38e4c6384824a2a5da3eb4f54da55ed962044a..6a9e361fed5eaee47bd8aa668021758b6a8ff6c8 100644 (file)
@@ -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);