diff options
author | Dan Williams <dcbw@redhat.com> | 2010-04-06 01:55:04 -0700 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2010-04-06 02:02:06 -0700 |
commit | a7e3d2acc29d3e7c267298df9a19a514ca628b37 (patch) | |
tree | c7e2cac2e8cb0984c931fd5d69ab7e01464315d9 | |
parent | d4c5930c0f46f66eee3da370009e6b8d6d77da08 (diff) |
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.
-rw-r--r-- | src/nm-device-olpc-mesh.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c index 2a1a235330..807db94bd3 100644 --- a/src/nm-device-olpc-mesh.c +++ b/src/nm-device-olpc-mesh.c @@ -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); |