mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-05 07:40:49 +00:00
olpc: ensure correct teardown of mesh device and companion wifi
If the mesh device gets removed first, ensure it cleans up its signal handlers so they don't get called when the wifi device is removed. Fixes warnings on NM shutdown where the mesh device object could be used after being freed.
This commit is contained in:
parent
b987bfdb8d
commit
b8e7e50c80
|
@ -105,6 +105,11 @@ struct _NMDeviceOlpcMeshPrivate
|
|||
NMDevice * companion;
|
||||
gboolean stage1_waiting;
|
||||
guint device_added_id;
|
||||
guint device_removed_id;
|
||||
guint cmp_state_changed_id;
|
||||
guint cmp_scanning_id;
|
||||
guint cmp_scanning_allowed_id;
|
||||
guint cmp_autoconnect_allowed_id;
|
||||
};
|
||||
|
||||
static void state_changed (NMDevice *device, NMDeviceState new_state,
|
||||
|
@ -434,6 +439,38 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
|
|||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
companion_cleanup (NMDeviceOlpcMesh *self)
|
||||
{
|
||||
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
|
||||
|
||||
if (priv->companion == NULL)
|
||||
return;
|
||||
|
||||
if (priv->cmp_state_changed_id) {
|
||||
g_signal_handler_disconnect (priv->companion, priv->cmp_state_changed_id);
|
||||
priv->cmp_state_changed_id = 0;
|
||||
}
|
||||
|
||||
if (priv->cmp_scanning_id) {
|
||||
g_signal_handler_disconnect (priv->companion, priv->cmp_scanning_id);
|
||||
priv->cmp_scanning_id = 0;
|
||||
}
|
||||
|
||||
if (priv->cmp_scanning_allowed_id) {
|
||||
g_signal_handler_disconnect (priv->companion, priv->cmp_scanning_allowed_id);
|
||||
priv->cmp_scanning_allowed_id = 0;
|
||||
}
|
||||
|
||||
if (priv->cmp_autoconnect_allowed_id) {
|
||||
g_signal_handler_disconnect (priv->companion, priv->cmp_autoconnect_allowed_id);
|
||||
priv->cmp_autoconnect_allowed_id = 0;
|
||||
}
|
||||
|
||||
priv->companion = NULL;
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_OLPC_MESH_COMPANION);
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
|
@ -451,10 +488,13 @@ dispose (GObject *object)
|
|||
wifi_utils_deinit (priv->wifi_data);
|
||||
|
||||
device_cleanup (self);
|
||||
companion_cleanup (self);
|
||||
|
||||
manager = nm_manager_get ();
|
||||
if (priv->device_added_id)
|
||||
g_signal_handler_disconnect (manager, priv->device_added_id);
|
||||
if (priv->device_removed_id)
|
||||
g_signal_handler_disconnect (manager, priv->device_removed_id);
|
||||
g_object_unref (manager);
|
||||
|
||||
G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object);
|
||||
|
@ -645,7 +685,6 @@ is_companion (NMDeviceOlpcMesh *self, NMDevice *other)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* FIXME detect when our companion leaves */
|
||||
priv->companion = other;
|
||||
|
||||
/* When we've found the companion, stop listening for other devices */
|
||||
|
@ -664,14 +703,17 @@ is_companion (NMDeviceOlpcMesh *self, NMDevice *other)
|
|||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
nm_device_get_iface (other));
|
||||
|
||||
g_signal_connect (G_OBJECT (other), "state-changed",
|
||||
G_CALLBACK (companion_state_changed_cb), self);
|
||||
g_signal_connect (G_OBJECT (other), "notify::scanning",
|
||||
G_CALLBACK (companion_notify_cb), self);
|
||||
g_signal_connect (G_OBJECT (other), "scanning-allowed",
|
||||
G_CALLBACK (companion_scan_allowed_cb), self);
|
||||
g_signal_connect (G_OBJECT (other), "autoconnect-allowed",
|
||||
G_CALLBACK (companion_autoconnect_allowed_cb), self);
|
||||
priv->cmp_state_changed_id = g_signal_connect (G_OBJECT (other), "state-changed",
|
||||
G_CALLBACK (companion_state_changed_cb), self);
|
||||
|
||||
priv->cmp_scanning_id = g_signal_connect (G_OBJECT (other), "notify::scanning",
|
||||
G_CALLBACK (companion_notify_cb), self);
|
||||
|
||||
priv->cmp_scanning_allowed_id = g_signal_connect (G_OBJECT (other), "scanning-allowed",
|
||||
G_CALLBACK (companion_scan_allowed_cb), self);
|
||||
|
||||
priv->cmp_autoconnect_allowed_id = g_signal_connect (G_OBJECT (other), "autoconnect-allowed",
|
||||
G_CALLBACK (companion_autoconnect_allowed_cb), self);
|
||||
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_OLPC_MESH_COMPANION);
|
||||
|
||||
|
@ -686,6 +728,15 @@ device_added_cb (NMManager *manager, NMDevice *other, gpointer user_data)
|
|||
is_companion (self, other);
|
||||
}
|
||||
|
||||
static void
|
||||
device_removed_cb (NMManager *manager, NMDevice *other, gpointer user_data)
|
||||
{
|
||||
NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (user_data);
|
||||
|
||||
if (other == NM_DEVICE_OLPC_MESH_GET_PRIVATE (self)->companion)
|
||||
companion_cleanup (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_companion_cb (gpointer user_data)
|
||||
{
|
||||
|
@ -708,6 +759,10 @@ check_companion_cb (gpointer user_data)
|
|||
|
||||
priv->device_added_id = g_signal_connect (manager, "device-added",
|
||||
G_CALLBACK (device_added_cb), self);
|
||||
if (!priv->device_removed_id) {
|
||||
priv->device_removed_id = g_signal_connect (manager, "device-removed",
|
||||
G_CALLBACK (device_removed_cb), self);
|
||||
}
|
||||
|
||||
/* Try to find the companion if it's already known to the NMManager */
|
||||
for (list = nm_manager_get_devices (manager); list ; list = g_slist_next (list)) {
|
||||
|
|
Loading…
Reference in a new issue