This commit shrinks the size of the internal hotplug callback structure
by removing unused fields, using the correctly sized types for matching
fields, and adding a new flags field whose bits control how the callback
structure should behave.
The hotplug callback handle ID counter has also been moved to the
context structure instead of being a global variable shared amongst all
contexts. This lets each context independently manage handle IDs and use
the maximum range of possible IDs.
Finally, the hotplug callback deregistration mechanism has been improved
to signal to the event handler that an explicit deregistration needs to
be handled. This removes the need to send a dummy hotplug message, which
was using an invalid libusb_hotplug_event value anyway that was causing
some compilers to complain.
Closes#373
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
This change add "libusb_" to every group and page definition (and
updates all references accordingly) so that generated man pages
are namespaced for libusb, thus avoiding possible conflict with
other packages.
Closes#131
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
Prior to this commit, API functions taking a libusb_device_handle
argument had the parameter named dev, handle, or dev_handle. This
commit changes the name of all libusb_device_handle parameters to
dev_handle in both the documentation and actual code.
Closes#132
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
Prior to this commit, it was possible to call certain functions from
within a hotplug or transfer completion callback that would in turn
attempt to handle events (e.g. any of the sync transfer APIs). This
is dangerous because certain events may cause the nested calls to
free memory that is currently in use by the previous calls.
This implementation uses thread-local storage to store a key within
the context that is set to a non-NULL value whenever event handling
is occurring. This allows us to detect when dangerous calls are made
from within event handling context. Such calls will return an error
code of LIBUSB_ERROR_BUSY.
Note that this implementation was chosen because of its portability.
It is supported on all platforms that libusb supports.
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
This change will ensure that the event pipe is only signalled
at most one time during the course of any incoming events. New
events that occur while the event pipe is in the signalled state
will not cause the event pipe to be signalled again.
This change will provide support for the use of native events on
the Windows/WinCE backends, as these events are binary and do not
"count" the number of times they are signalled.
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
To further consolidate libusb internal events, this change removes
the hotplug pipe. Hotplug messages are now kept in a list within the
context, and the event pipe is signalled when a new hotplug message
is added. When handling events, the hotplug messages will be processed
from the list instead of from a separate pipe.
This change is greatly beneficial for the Windows/WinCE backends which
do not allow pipes to be used in the WaitFor* functions.
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
libusb/hotplug.c:46: warning: multiple use of section label 'intro'
while adding section, (first occurrence: libusb/core.c, line 79)
Use label "hotplug_intro" instead of "intro"
Calling user callbacks with locks held is a bad idea and should be avoided
whenever possible. Before this patch this could lead ie to the following hang:
1) User calls libusb_hotplug_register_callback with the
LIBUSB_HOTPLUG_ENUMERATE flag
2) libusb_hotplug_register_callback calls the user callback while holding the
hotplug_cbs_lock
3) The callback calls a synchronous libusb function
4) The synchronous libusb function calls libusb_handle_events
5) There is an hotplug event waiting in the hotplug pipe and
libusb_handle_events calls usbi_hotplug_match
6) usbi_hotplug_match tries to take the lock a 2nd time
7) hang / assert / abort (depending on the platform)
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit should fix issues with active transfers when a device is
disconnected. The backend is responsible for making sure the completion
callbacks are made, not the hotplug code. This should fix a number of
issues including duplicate callbacks and segmentation faults.
References #124.
* Instead of passing NULL for the context to hotplug callbacks, if the
context happens to be the default context, always pass the explicit
context pointer.
This serves 2 purposes:
1) We use lazy free-ing of the callback structure, for it to be actually
free-ed usbi_hotplug_match() needs to be called. This ensures this actually
happens (rather then waiting for a hotplug event to arrive, and not freeing
the callback as long as no such event arrives).
2) It causes libusb_handle_events to return to its caller on a call to
libusb_hotplug_deregister_callback, which is very useful for apps which use
a thread to do their apps (hotplug) event handling, otherwise that thread will
hang when the app tries to stop until some event happens.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
So that the device parameter can be NULL, in combination with a 0
events parameter, to be used to force lazy deregistration.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
The internal API is changing as follows:
- Adding two new functions. usbi_connect_device, and usbi_disconnect_device.
Backends must call these functions to add them to the context's device list
at one of two places: initial enumeration (done at init), and on device
attach and removal. These functions need to be called once per context.
- Backends that support hotplug should not provide a get_device_list funtion.
This function is now deprecated and will likely be removed once all backends
support hotplug.
The external API is changing as follows:
- Two new functions have been added to register and deregister callbacks for
hotplug notification: libusb_hotplug_register_callback(),
libusb_hotplug_deregister_callback(). Hotplug callbacks are called by
libusb_handle_events(). Details of the new API can be found in libusb.h.
- A new capability check has been added to check for hotplug support. See
LIBUSB_CAP_HAS_HOTPLUG.
Aa suggested by Xiaofan add new example has been added to show how to use
the new external hotplug API. See examples/hotplugtest.c.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>