Hi,

On 06/13/2013 08:57 PM, Chris Dickens wrote:
> Hi,
>
> I see from the git log that the hotplug_poll() function was added for 
> applications that perhaps handled hotplug notification on their own. Given 
> the structure of the new hotplug code, it appears that a context will not be 
> successfully created unless the hotplug monitoring thread can be created. So 
> one can assume that if a libusb context was created, a hotplug event thread 
> is running.

Correct.

<snip>

> I do not fully understand why this second path is necessary. If the idea is 
> that a device may take a long time to enumerate, the structure doesn't help 
> this because the linux_hotplug_lock is held for the entire duration of the 
> enumeration/disconnect process, thereby blocking the other path from handling 
> anything at the same time.
>
> Can someone please clarify the purpose/reasoning?

Ok, so there are a number of scenarios here, all involving an app doing
hotplug handling on its own.

Scenario A: An app doing hotplug handling on its own, old libusb without
hotplug handling, in this case:

1) The app will establish its own connection to the udev netlink socket
2) It will poll on this
3) When a device-add is received, it will call libusb_get_device_list
4) libusb_get_device_list will walk through sysfs (which is guaranteed
    to have an entry for the new device before the netlink msg is send),
    and enumerate all devices in there including the newly added one
5) The app will walk through the returned libusb_device list, until it
    finds the device matching the udev event
6) The app starts using the new libusb_device

Scenario B: An app doing hotplug handling on its own, new libusb with
hotplug handling, before I added the hotplug_poll function in this case:

1) libusb will establish a connection to the udev netlink socket
2) libusb will create a hotplug event thread, and that thread will poll
    on libusb's connection
3) The app will establish its own connection to the udev netlink socket
4) The app will poll on its own connection
5) A new device gets plugged in
6) Both the app and libusb's hotplug thread get a device-added event,
    lets assume the best case scenario and libusb gets it first and starts
    enumerating the new device, this takes time, so while the hotplug thread
    is busy enumerating the device...
7) The app calls libusb_get_device_list, with a hotplug capable libusb this
    does not do an expensive re-enumaration of all devices, it simply returns
    a copy of the cached libusb_device list inside libusb
8) libusb's hotplug thread finishes enumeration and when enumeration was
    successful, adds the new device to libusb's cached device list
9) Note the adding of the new device to the list is done after the app got
    a copy, so:
10) The app will walk through the returned libusb_device list, until it
    finds the device matching the udev event
11) The app never finds a matching device, and decides to ignore the event
12) The user is unhappy because the app does not see the newly plugged in
    device.

Scenario C: An app doing hotplug handling on its own, new libusb with
hotplug handling, with the hotplug_poll function in this case:

1) libusb will establish a connection to the udev netlink socket
2) libusb will create a hotplug event thread, and that thread will poll
    on libusb's connection
3) The app will establish its own connection to the udev netlink socket
4) The app will poll on its own connection
5) A new device gets plugged in
6) Both the app and libusb's hotplug thread get a device-added event
7) The app calls libusb_get_device_list, which calls hotplug_poll,
    hotplug_poll checks for udev events on the netlink socket, now there
    are 2 sub-scenarios possible:
    7.1) The hotplug event thread has not run yet, and hotplug_poll reads
         the event itself and enumerates the device from the thread which
         called libusb_get_device_list;
    7.2) The hotplug event thread has already read the netlink socket, and
         is busy processing it (iow the timing works out as in Scenario B
         from above), in this case the hotplug-event thread holds the
         linux_hotplug_lock, and hotplug_poll has to wait till it acquires
         the lock. Once it has the lock it finds no netlink msg waiting,
         releases the lock and returns.
    Note that in both scenarios once hotplug_poll returns the
    device-enumeration has completed, and the device will have been added
    to libusb's cached device list
8) libusb_get_device_list returns a copy of libusb's cached device list
9) The app will walk through the returned libusb_device list, until it
    finds the device matching the udev event
10) The app starts using the new libusb_device
11) The user is happy because the app sees the newly plugged in device.

I hope this helps to make things clear.

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