Hi,

On 06/26/2013 09:10 AM, Chris Dickens wrote:
> Hi,
>
> I have noticed some behavior that I believe most users will find undesirable. 
> The situation is this:
>
> 1) The application opens a libusb device, which adds this to the poll fds
> 2) While the device is opened and IO is occurring, the device reboots or 
> otherwise disappears from USB
> 3) When the device disappears, the device's fd immediately triggers a POLLERR 
> condition, which is immediately seen by any active event handlers
> 4) At some later point in time, which varies greatly from hundreds of 
> microseconds to several seconds, the udev monitor will get the disconnect 
> notification and will then process the hotplug disconnect, removing the 
> device from all contexts' device list and calling registers hotplug callbacks
> 5) Between the time that the POLLERR condition is seen and the udev monitor 
> is notified, the application gets the list of devices, which still contains 
> the device that has been disconnected (because it only gets removed by the 
> udev monitor thread, which hasn't seen the removal yet). The application 
> tries to open the device, but it fails with LIBUSB_ERROR_NO_DEVICE when the 
> open() call to the fd fails. It continues to show up in the device list and 
> fail to open up to the point that the udev monitor thread receives the 
> notification of removal.
>
> It occurs to me that if a usb device is open and in the poll fd set, this 
> will provide relatively immediate notification of device removal, because of 
> the POLLERR condition. Once this condition is seen, immediate action can be 
> taken to remove the device from the device lists and notify the hotplug 
> callbacks. I don't know why udev can sometimes take up to several seconds to 
> send the event, but it is undesirable to have a device listed while it is 
> known to be unusable. Prior to hotplug, the described scenario would not have 
> occurred since the usb device tree was scanned upon every
> get_device_list() call.

Hmm, the libusb_poll call in get_device_list() should make this quite hard to 
trigger, this will only
happen if udev has not yet read the kernel event, and send an event on its own 
socket. Which likely
means that your setup is somehow cpu starved.

With that said:

> I have played around and have come with an improvement for this situation. 
> With my patch, any open devices that are disconnected will immediately be 
> removed from all contexts' device list and have all hotplug callbacks called.

Although I'm not really a fan of having 2 device removed codepaths, I think 
this is probably a
simple and useful patch. Can you post the patch for review please?

 > Devices that are not currently open will still be subject to the speed of 
 > the udev monitor and may still show up in a context's device list, but this 
 > can also be improved to only happen at most one time. If an attempt to open 
 > a device that has been disconnected is made, it can be handled just like the 
 > POLLERR condition. In both of these situations, when the udev monitor
> thread finally gets the removal message, it will try to remove the device (by 
> its session ID) but will find it has already been removed.

This sounds like a lot of dark magic for little gain, I would not bother with 
attempting something
like this, I don't want to add device_disconnect calls to each place were we 
can get a ENOENT or
ENODEV error, just to speed up detection of device removal by a few ms.

Regards,

Hans

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
libusbx-devel mailing list
libusbx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusbx-devel

Reply via email to