From 6b34f996699a80c249d2cccfe369b3b61e70d4ce Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 10 Dec 2018 14:43:30 +1000 Subject: [PATCH] common: fix udev-based device removal libgudev allocs a new GUdevDevice object for each event, so the pointer value for the 'add' udev event differs from the one for the 'remove' event. If we use the pointer value as hash table key, we'll never remove the device. Switch to use the syspath of the device instead, that one is unique per device. Fixes #309 --- panels/common/gsd-device-manager-udev.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/panels/common/gsd-device-manager-udev.c b/panels/common/gsd-device-manager-udev.c index aa9304232..105c8e987 100644 --- a/panels/common/gsd-device-manager-udev.c +++ b/panels/common/gsd-device-manager-udev.c @@ -122,6 +122,7 @@ add_device (GsdUdevDeviceManager *manager, { GUdevDevice *parent; GsdDevice *device; + gchar *syspath; parent = g_udev_device_get_parent (udev_device); @@ -129,7 +130,8 @@ add_device (GsdUdevDeviceManager *manager, return; device = create_device (udev_device); - g_hash_table_insert (manager->devices, g_object_ref (udev_device), device); + syspath = g_strdup (g_udev_device_get_sysfs_path (udev_device)); + g_hash_table_insert (manager->devices, syspath, device); g_signal_emit_by_name (manager, "device-added", device); } @@ -138,17 +140,19 @@ remove_device (GsdUdevDeviceManager *manager, GUdevDevice *udev_device) { GsdDevice *device; + gchar *syspath; - device = g_hash_table_lookup (manager->devices, udev_device); + syspath = g_strdup (g_udev_device_get_sysfs_path (udev_device)); + device = g_hash_table_lookup (manager->devices, syspath); if (!device) return; - g_hash_table_steal (manager->devices, udev_device); + g_hash_table_steal (manager->devices, syspath); g_signal_emit_by_name (manager, "device-removed", device); g_object_unref (device); - g_object_unref (udev_device); + g_free (syspath); } static void @@ -173,8 +177,8 @@ gsd_udev_device_manager_init (GsdUdevDeviceManager *manager) const gchar *subsystems[] = { "input", NULL }; GList *devices, *l; - manager->devices = g_hash_table_new_full (NULL, NULL, - (GDestroyNotify) g_object_unref, + manager->devices = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); manager->udev_client = g_udev_client_new (subsystems); -- 2.24.0