hughsie / libgusb

GUsb is a GObject wrapper for libusb1
GNU Lesser General Public License v2.1
25 stars 21 forks source link

context: Fix hotplug handling and signal emission during enumerate #50

Closed benzea closed 3 years ago

benzea commented 3 years ago

Initial device enumeration may happen in a random order. This causes issues if someone calls g_usb_device_get_parent from the "device-added" signal handler. The problem is. that this will cause an infinite recursion as GUsb tries to enumerate again, which results in the device to be added. Also, the order of devices is random and resolving the parent requires the full list of devices. As such, we should delay emission until the internal array has been filled.

To fix this, emit the signals from g_usb_context_enumerate.

Also, while changing this, it became obvious that libusb hotplug callback is updating priv->devices from the libusb thread, only pushing it to an idle handler when the signal is emitted. Doing this is unsafe if hotplug events arrive during enumeration. Push libusb event into the mainloop immediately in order to process it.

Doing means that any libusb hotplug events arriving during g_usb_context_enumerate will be handled after the function has returned. Making all possible corner cases behave correctly.

benzea commented 3 years ago

OK, updated.

I changed one of the comments slightly. I think there is a theoretical change in behaviour. i.e. before libusb hotplug events could come through to the application even before g_usb_context_enumerate was called. Now, hotplug events can only happen during/after g_usb_context_enumerate.

I think that is fine, just wanted to point it out in case it might be relevant.

hughsie commented 3 years ago

I think that is fine, just wanted to point it out in case it might be relevant.

I think you fixed a bug! Thanks!