summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2013-08-21 14:46:45 +0200
committerHans de Goede <hdegoede@redhat.com>2013-08-21 14:46:45 +0200
commita06eafdc528d5f3ea21a26c34ceaa13e09dfd4f3 (patch)
treeba606d83d26c30e91cc1801c67d1268df4cb9481
parent0fc304da83595da9830bf368f66312ffd793f10c (diff)
downloadlibusb-a06eafdc528d5f3ea21a26c34ceaa13e09dfd4f3.tar.gz
hotplug: Document LIBUSB_HOTPLUG_ENUMERATE gotchas
When libusb_hotplug_register_callback gets called with the LIBUSB_HOTPLUG_ENUMERATE flag, there may still be hotplug events pending in the hotplug pipe, waiting for dispatching from libusb_handle_events. This means that the user callback can be called twice for arrival of the same device, once from libusb_hotplug_register_callback, since the device is already part of the usb_devs list, and once from libusb_handle_events when it reads the event from the hotplug pipe. This could be fixed by adding a mechanism to pause hotplug handling, then drain the hotplug pipe (ie by calling libusb_handle_events from libusb_hotplug_register_callback), before iterating over the usb_devs list, and then un-pausing hotplug handling afterwards, doing this however requires a lot of hairy code, which will be prone to dead-locking. OTOH it is quite simple for user applications which care about this to detect this and ignore the 2nd call, so lets simply document this may happen and be done with it. Note that this is also the solution which ie libudev has choosen, there is no way with libudev to get a device-list + listen for device arrival / removal without running into the same problem. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r--libusb/libusb.h12
-rw-r--r--libusb/version_nano.h2
2 files changed, 13 insertions, 1 deletions
diff --git a/libusb/libusb.h b/libusb/libusb.h
index 875b6f1..97aeecc 100644
--- a/libusb/libusb.h
+++ b/libusb/libusb.h
@@ -1897,6 +1897,18 @@ typedef int (LIBUSB_CALL *libusb_hotplug_callback_fn)(libusb_context *ctx,
* armed until either it is deregistered with libusb_hotplug_deregister_callback()
* or the supplied callback returns 1 to indicate it is finished processing events.
*
+ * If the \ref LIBUSB_HOTPLUG_ENUMERATE is passed the callback will be
+ * called with a \ref LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED for all devices
+ * already plugged into the machine. Note that libusbx modifies its internal
+ * device list from a separate thread, while calling hotplug callbacks from
+ * libusb_handle_events(), so it is possible for a device to already be present
+ * on, or removed from, its internal device list, while the hotplug callbacks
+ * still need to be dispatched. This means that when using \ref
+ * LIBUSB_HOTPLUG_ENUMERATE, your callback may be called twice for the arrival
+ * of the same device, once from libusb_hotplug_register_callback() and once
+ * from libusb_handle_events(); and/or your callback may be called for the
+ * removal of a device for which an arrived call was never made.
+ *
* Since version 1.0.16, \ref LIBUSBX_API_VERSION >= 0x01000102
*
* \param[in] ctx context to register this callback with
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index c265037..4c3e712 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10815
+#define LIBUSB_NANO 10816