gdbus: Add g_clear_dbus_signal_subscription() inline convenience function

This is like g_clear_signal_handler(), but for GDBus signal subscriptions.

Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
Simon McVittie 2025-02-10 11:05:53 +00:00
parent c5d82f9099
commit 534f3462a2
2 changed files with 55 additions and 9 deletions

View File

@ -603,6 +603,46 @@ GIO_AVAILABLE_IN_ALL
void g_dbus_connection_signal_unsubscribe (GDBusConnection *connection,
guint subscription_id);
/**
* g_clear_dbus_signal_subscription: (skip)
* @subscription_id_pointer: (not optional) (inout): A pointer to either a
* subscription id obtained from g_dbus_connection_signal_subscribe(),
* or zero.
* @connection: The connection from which the subscription ID was obtained.
* This pointer may be %NULL or invalid, if the subscription ID is zero.
*
* If @subscription_id_pointer points to a nonzero subscription ID,
* unsubscribe from that D-Bus signal subscription as if via
* g_dbus_connection_signal_unsubscribe().
* Also set the value pointed to by @subscription_id_pointer to zero,
* which is not a valid subscription ID.
*
* This convenience function for C code helps to ensure that each signal
* subscription is unsubscribed exactly once, similar to g_clear_object()
* and g_clear_signal_handler().
*
* Since: 2.84
*/
GLIB_AVAILABLE_STATIC_INLINE_IN_2_84
static inline void g_clear_dbus_signal_subscription (guint *subscription_id_pointer,
GDBusConnection *connection);
GLIB_AVAILABLE_STATIC_INLINE_IN_2_84
static inline void
g_clear_dbus_signal_subscription (guint *subscription_id_pointer,
GDBusConnection *connection)
{
guint subscription_id;
/* Suppress "Not available before" warning */
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
subscription_id = g_steal_handle_id (subscription_id_pointer);
G_GNUC_END_IGNORE_DEPRECATIONS
if (subscription_id > 0)
g_dbus_connection_signal_unsubscribe (connection, subscription_id);
}
/* ---------------------------------------------------------------------------------------------------- */
/**

View File

@ -793,12 +793,18 @@ test_connection_signals (void)
g_assert_cmpint (count_s4, ==, 2);
g_assert_cmpint (count_s5, ==, 1);
g_dbus_connection_signal_unsubscribe (c1, g_steal_handle_id (&s1));
g_dbus_connection_signal_unsubscribe (c1, g_steal_handle_id (&s2));
g_dbus_connection_signal_unsubscribe (c1, g_steal_handle_id (&s3));
g_dbus_connection_signal_unsubscribe (c1, g_steal_handle_id (&s1b));
g_dbus_connection_signal_unsubscribe (c1, g_steal_handle_id (&s4));
g_dbus_connection_signal_unsubscribe (c1, g_steal_handle_id (&s5));
g_assert_cmpint (s1, !=, 0);
g_clear_dbus_signal_subscription (&s1, c1);
g_assert_cmpint (s1, ==, 0);
/* g_clear_dbus_signal_subscription() is idempotent, with no warnings */
g_clear_dbus_signal_subscription (&s1, c1);
g_assert_cmpint (s1, ==, 0);
g_clear_dbus_signal_subscription (&s2, c1);
g_clear_dbus_signal_subscription (&s3, c1);
g_clear_dbus_signal_subscription (&s1b, c1);
g_clear_dbus_signal_subscription (&s4, c1);
g_clear_dbus_signal_subscription (&s5, c1);
g_object_unref (c1);
g_object_unref (c2);
@ -852,8 +858,8 @@ test_match_rule (GDBusConnection *connection,
g_assert_cmpint (emissions, ==, 1);
g_assert_cmpint (matches, ==, should_match ? 1 : 0);
g_dbus_connection_signal_unsubscribe (connection, g_steal_handle_id (&subscription_ids[0]));
g_dbus_connection_signal_unsubscribe (connection, g_steal_handle_id (&subscription_ids[1]));
g_clear_dbus_signal_subscription (&subscription_ids[0], connection);
g_clear_dbus_signal_subscription (&subscription_ids[1], connection);
}
static void
@ -1132,7 +1138,7 @@ test_connection_filter (void)
timeout_mainloop_id = g_timeout_add (30000, test_connection_filter_on_timeout, NULL);
g_main_loop_run (loop);
g_source_remove (timeout_mainloop_id);
g_dbus_connection_signal_unsubscribe (c, g_steal_handle_id (&signal_handler_id));
g_clear_dbus_signal_subscription (&signal_handler_id, c);
/* now test some combinations... */
filter_id = g_dbus_connection_add_filter (c,