summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2010-04-06 01:55:04 -0700
committerDan Williams <dcbw@redhat.com>2010-04-06 02:02:06 -0700
commita7e3d2acc29d3e7c267298df9a19a514ca628b37 (patch)
treec7e2cac2e8cb0984c931fd5d69ab7e01464315d9
parentd4c5930c0f46f66eee3da370009e6b8d6d77da08 (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.c43
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);