mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-24 23:00:07 +01:00
olpc-mesh: fix companion device detection crash
The original OLPC mesh patch confused g_source_remove() with g_signal_handler_disconnect(), so the signal handler that the mesh device creates for the managers 'device-added' signal was getting called after that mesh device instance was freed, which is of course bad.
This commit is contained in:
parent
d4c5930c0f
commit
a7e3d2acc2
1 changed files with 25 additions and 18 deletions
|
|
@ -109,7 +109,7 @@ struct _NMDeviceOlpcMeshPrivate
|
|||
|
||||
NMDevice * companion;
|
||||
gboolean stage1_waiting;
|
||||
guint device_added_cb;
|
||||
guint device_added_id;
|
||||
};
|
||||
|
||||
static GQuark
|
||||
|
|
@ -345,9 +345,7 @@ device_cleanup (NMDeviceOlpcMesh *self)
|
|||
static void
|
||||
real_take_down (NMDevice *dev)
|
||||
{
|
||||
NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (dev);
|
||||
|
||||
device_cleanup (self);
|
||||
device_cleanup (NM_DEVICE_OLPC_MESH (dev));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -650,24 +648,24 @@ real_act_stage4_ip4_config_timeout (NMDevice *dev,
|
|||
|
||||
|
||||
static void
|
||||
nm_device_olpc_mesh_dispose (GObject *object)
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (object);
|
||||
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
|
||||
NMManager *manager;
|
||||
|
||||
if (priv->dispose_has_run) {
|
||||
G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object);
|
||||
return;
|
||||
}
|
||||
|
||||
priv->dispose_has_run = TRUE;
|
||||
|
||||
device_cleanup (self);
|
||||
|
||||
if (priv->device_added_cb != 0)
|
||||
g_source_remove (priv->device_added_cb);
|
||||
|
||||
priv->device_added_cb = 0;
|
||||
manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL);
|
||||
if (priv->device_added_id)
|
||||
g_signal_handler_disconnect (manager, priv->device_added_id);
|
||||
g_object_unref (manager);
|
||||
|
||||
G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object);
|
||||
}
|
||||
|
|
@ -731,7 +729,7 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass)
|
|||
object_class->constructor = constructor;
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
object_class->dispose = nm_device_olpc_mesh_dispose;
|
||||
object_class->dispose = dispose;
|
||||
|
||||
parent_class->get_type_capabilities = NULL;
|
||||
parent_class->get_generic_capabilities = real_get_generic_capabilities;
|
||||
|
|
@ -862,6 +860,7 @@ is_companion (NMDeviceOlpcMesh *self, NMDevice *other)
|
|||
{
|
||||
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
|
||||
struct ether_addr their_addr;
|
||||
NMManager *manager;
|
||||
|
||||
if (!NM_IS_DEVICE_WIFI (other))
|
||||
return FALSE;
|
||||
|
|
@ -876,14 +875,21 @@ is_companion (NMDeviceOlpcMesh *self, NMDevice *other)
|
|||
/* FIXME detect when our companion leaves */
|
||||
priv->companion = other;
|
||||
|
||||
g_source_remove (priv->device_added_cb);
|
||||
priv->device_added_cb = 0;
|
||||
/* When we've found the companion, stop listening for other devices */
|
||||
manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL);
|
||||
if (priv->device_added_id) {
|
||||
g_signal_handler_disconnect (manager, priv->device_added_id);
|
||||
priv->device_added_id = 0;
|
||||
}
|
||||
g_object_unref (manager);
|
||||
|
||||
nm_device_state_changed (NM_DEVICE (self),
|
||||
NM_DEVICE_STATE_DISCONNECTED,
|
||||
NM_DEVICE_STATE_REASON_NONE);
|
||||
|
||||
nm_debug ("Found companion device: %s", nm_device_get_iface (other));
|
||||
nm_info ("(%s): found companion WiFi device %s",
|
||||
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);
|
||||
|
|
@ -922,18 +928,19 @@ check_companion_cb (gpointer user_data)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (priv->device_added_cb != 0)
|
||||
if (priv->device_added_id != 0)
|
||||
return FALSE;
|
||||
|
||||
manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL);
|
||||
|
||||
priv->device_added_cb = g_signal_connect (manager, "device-added",
|
||||
priv->device_added_id = g_signal_connect (manager, "device-added",
|
||||
G_CALLBACK (device_added_cb), self);
|
||||
|
||||
list = nm_manager_get_devices (manager);
|
||||
for (; list != NULL ; list = list->next)
|
||||
/* 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)) {
|
||||
if (is_companion (self, NM_DEVICE (list->data)))
|
||||
break;
|
||||
}
|
||||
|
||||
g_object_unref (manager);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue