Never add two devices to the daemon with the same ID

Deduplicate based on the ID, without assuming the devices will be the same
in-memory object. Also, only emit the changed signal if the device is waiting
for a replug.

Fixes https://github.com/hughsie/fwupd/issues/364
This commit is contained in:
Richard Hughes 2018-01-12 20:35:13 +00:00
parent 8da530475d
commit e1fe34f1ec
2 changed files with 25 additions and 4 deletions

View File

@ -307,7 +307,7 @@ fu_device_list_remove (FuDeviceList *self, FuDevice *device)
g_return_if_fail (FU_IS_DEVICE (device));
/* check the device already exists */
item = fu_device_list_find_by_device (self, device);
item = fu_device_list_find_by_id (self, fu_device_get_id (device), NULL);
if (item == NULL) {
g_debug ("device %s not found", fu_device_get_id (device));
return;
@ -384,9 +384,9 @@ fu_device_list_add (FuDeviceList *self, FuDevice *device)
g_return_if_fail (FU_IS_DEVICE_LIST (self));
g_return_if_fail (FU_IS_DEVICE (device));
/* verify the device does not already exist */
item = fu_device_list_find_by_device (self, device);
if (item != NULL) {
/* is the device waiting to be replugged? */
item = fu_device_list_find_by_id (self, fu_device_get_id (device), NULL);
if (item != NULL && item->remove_id != 0) {
g_debug ("found existing device %s, reusing item",
fu_device_get_id (item->device));
if (item->remove_id != 0) {
@ -397,6 +397,13 @@ fu_device_list_add (FuDeviceList *self, FuDevice *device)
return;
}
/* verify the device does not already exist */
if (item != NULL) {
g_debug ("device %s already exists, ignoring",
fu_device_get_id (item->device));
return;
}
/* verify a compatible device does not already exist */
item = fu_device_list_get_by_guids (self, fu_device_get_guids (device));
if (item != NULL && item->remove_id != 0) {

View File

@ -517,6 +517,7 @@ static void
fu_device_list_delay_func (void)
{
g_autoptr(FuDevice) device1 = fu_device_new ();
g_autoptr(FuDevice) device2 = fu_device_new ();
g_autoptr(FuDeviceList) device_list = fu_device_list_new ();
guint added_cnt = 0;
guint changed_cnt = 0;
@ -541,6 +542,19 @@ fu_device_list_delay_func (void)
g_assert_cmpint (removed_cnt, ==, 0);
g_assert_cmpint (changed_cnt, ==, 0);
/* add the same device again */
fu_device_list_add (device_list, device1);
g_assert_cmpint (added_cnt, ==, 1);
g_assert_cmpint (removed_cnt, ==, 0);
g_assert_cmpint (changed_cnt, ==, 0);
/* add a device with the same ID */
fu_device_set_id (device2, "device1");
fu_device_list_add (device_list, device2);
g_assert_cmpint (added_cnt, ==, 1);
g_assert_cmpint (removed_cnt, ==, 0);
g_assert_cmpint (changed_cnt, ==, 0);
/* spin a bit */
fu_test_loop_run_with_timeout (10);
fu_test_loop_quit ();