From 13c30f987c41e154912465a20d2fe28de59b7742 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 14 Jan 2020 12:34:40 +0100 Subject: [PATCH] core/bluetooth: don't use nm_dbus_connection_signal_subscribe_object_manager() nm_dbus_connection_signal_subscribe_object_manager() wraps the subscription. The problem is that this requires to pass a destroy notify function for cleaning up. Such a destroy notify function will result in an idle source when unsubscribing, which keeps the associated GMainContext alive (until it gets iterated some more). That seems error prone and outright unsuitable for NMClient. While the helper may be useful, it cannot be used by NMClient. So, there is only one user of this function and we don't expect a second one. It seems better to get rid of this wrapper and implement it directly. --- src/devices/bluetooth/nm-bluez-manager.c | 59 ++++++++++++++++++------ 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c index ef087d83e9..1c494a11d7 100644 --- a/src/devices/bluetooth/nm-bluez-manager.c +++ b/src/devices/bluetooth/nm-bluez-manager.c @@ -2071,9 +2071,12 @@ _dbus_handle_interface_removed (NMBluezManager *self, } static void -_dbus_managed_objects_changed_cb (const char *object_path, - GVariant *added_interfaces_and_properties, - const char *const*removed_interfaces, +_dbus_managed_objects_changed_cb (GDBusConnection *connection, + const char *sender_name, + const char *arg_object_path, + const char *interface_name, + const char *signal_name, + GVariant *parameters, gpointer user_data) { NMBluezManager *self = user_data; @@ -2081,17 +2084,46 @@ _dbus_managed_objects_changed_cb (const char *object_path, BzDBusObj *bzobj = NULL; gboolean changed; + nm_assert (nm_streq0 (interface_name, DBUS_INTERFACE_OBJECT_MANAGER)); + if (priv->get_managed_objects_cancellable) { /* we still wait for the initial GetManagedObjects(). Ignore the event. */ return; } - if (!added_interfaces_and_properties) { - changed = _dbus_handle_interface_removed (self, object_path, &bzobj, removed_interfaces); + if (nm_streq (signal_name, "InterfacesAdded")) { + gs_unref_variant GVariant *interfaces_and_properties = NULL; + const char *object_path; + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(oa{sa{sv}})"))) + return; + + g_variant_get (parameters, + "(&o@a{sa{sv}})", + &object_path, + &interfaces_and_properties); + + _dbus_handle_interface_added (self, object_path, interfaces_and_properties, FALSE); + return; + } + + if (nm_streq (signal_name, "InterfacesRemoved")) { + gs_free const char **interfaces = NULL; + const char *object_path; + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(oas)"))) + return; + + g_variant_get (parameters, + "(&o^a&s)", + &object_path, + &interfaces); + + changed = _dbus_handle_interface_removed (self, object_path, &bzobj, interfaces); if (changed) _dbus_process_changes (self, bzobj, "dbus-iface-removed"); - } else - _dbus_handle_interface_added (self, object_path, added_interfaces_and_properties, FALSE); + return; + } } static void @@ -2231,12 +2263,13 @@ name_owner_changed (NMBluezManager *self, priv->get_managed_objects_cancellable = g_cancellable_new (); - priv->managed_objects_changed_id = nm_dbus_connection_signal_subscribe_object_manager (priv->dbus_connection, - priv->name_owner, - NM_BLUEZ_MANAGER_PATH, - _dbus_managed_objects_changed_cb, - self, - NULL); + priv->managed_objects_changed_id = nm_dbus_connection_signal_subscribe_object_manager_plain (priv->dbus_connection, + priv->name_owner, + NM_BLUEZ_MANAGER_PATH, + NULL, + _dbus_managed_objects_changed_cb, + self, + NULL); priv->properties_changed_id = nm_dbus_connection_signal_subscribe_properties_changed (priv->dbus_connection, priv->name_owner,