summaryrefslogtreecommitdiff
path: root/src/devices/wifi/nm-iwd-manager.c
diff options
context:
space:
mode:
authorAndrew Zaborowski <andrew.zaborowski@intel.com>2018-01-22 19:22:55 +0100
committerThomas Haller <thaller@redhat.com>2018-02-09 21:30:46 +0100
commit86dd4000494de4d0050129ac7632a22840a103cb (patch)
tree7fc46219032a9743aa464f594bacf6d071996956 /src/devices/wifi/nm-iwd-manager.c
parentd32987fdd19b14b16409f6f8578e66e26bb3793f (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.c48
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);
}