diff options
author | Andrew Zaborowski <andrew.zaborowski@intel.com> | 2018-01-22 19:22:55 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-02-09 21:30:46 +0100 |
commit | 86dd4000494de4d0050129ac7632a22840a103cb (patch) | |
tree | 7fc46219032a9743aa464f594bacf6d071996956 /src/devices/wifi/nm-iwd-manager.c | |
parent | d32987fdd19b14b16409f6f8578e66e26bb3793f (diff) |
iwd: recreate GDbusObjectManagerClient on reconnect
Reuse the apparent workaround from libnm/nm-client.c in which the
GDbusObjectManagerClient is recreated every time the name owner
pops up, instead of creating it once and using that object forever.
Resubscribe to all the signals on the new object. The initial
GDbusObjectManager we create is only used to listed for the name-owner
changes.
There's nothing in gdbus docs that justifies doing that but there
doesn't seem to be any way to reliably receive all the signals from
the dbus service the normal way. The signals do appear on dbus-monitor
and the gdbus apparently subscribes to those signals with AddMatch()
correctly but they sometimes won't be received by the client code,
unless this workaround is applied.
While making changes to got_object_manager, don't destroy the
cancellable there as it is supposed to be used throughout the
NMIwdManager life.
Diffstat (limited to 'src/devices/wifi/nm-iwd-manager.c')
-rw-r--r-- | src/devices/wifi/nm-iwd-manager.c | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c index 26553fd6b..68d50a587 100644 --- a/src/devices/wifi/nm-iwd-manager.c +++ b/src/devices/wifi/nm-iwd-manager.c @@ -451,6 +451,8 @@ update_known_networks (NMIwdManager *self) g_object_unref (known_networks_if); } +static void prepare_object_manager (NMIwdManager *self); + static void name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data) { @@ -461,20 +463,9 @@ name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data) nm_assert (object_manager == priv->object_manager); if (_om_has_name_owner (object_manager)) { - GList *objects, *iter; - - priv->running = true; - - objects = g_dbus_object_manager_get_objects (object_manager); - for (iter = objects; iter; iter = iter->next) - object_added (self, G_DBUS_OBJECT (iter->data)); - - g_list_free_full (objects, g_object_unref); - - if (priv->agent_id) - register_agent (self); - - update_known_networks (self); + g_signal_handlers_disconnect_by_data (object_manager, self); + g_clear_object (&priv->object_manager); + prepare_object_manager (self); } else { const GSList *devices, *iter; @@ -549,8 +540,6 @@ got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) GDBusObjectManager *object_manager; GDBusConnection *connection; - g_clear_object (&priv->cancellable); - object_manager = g_dbus_object_manager_client_new_for_bus_finish (result, &error); if (object_manager == NULL) { _LOGE ("failed to acquire IWD Object Manager: Wi-Fi will not be available (%s)", @@ -561,10 +550,6 @@ got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) priv->object_manager = object_manager; - g_signal_connect (priv->object_manager, "interface-added", - G_CALLBACK (interface_added), self); - g_signal_connect (priv->object_manager, "interface-removed", - G_CALLBACK (interface_removed), self); g_signal_connect (priv->object_manager, "notify::name-owner", G_CALLBACK (name_owner_changed), self); @@ -580,7 +565,27 @@ got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) g_clear_error (&error); } - name_owner_changed (G_OBJECT (object_manager), NULL, self); + if (_om_has_name_owner (object_manager)) { + GList *objects, *iter; + + priv->running = true; + + g_signal_connect (priv->object_manager, "interface-added", + G_CALLBACK (interface_added), self); + g_signal_connect (priv->object_manager, "interface-removed", + G_CALLBACK (interface_removed), self); + + objects = g_dbus_object_manager_get_objects (object_manager); + for (iter = objects; iter; iter = iter->next) + object_added (self, G_DBUS_OBJECT (iter->data)); + + g_list_free_full (objects, g_object_unref); + + if (priv->agent_id) + register_agent (self); + + update_known_networks (self); + } } static void @@ -644,6 +649,7 @@ nm_iwd_manager_init (NMIwdManager *self) G_CALLBACK (device_added), self); priv->cancellable = g_cancellable_new (); + prepare_object_manager (self); } |