| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
| |
When a transfer is submitted, the device is referenced in libusb_submit_transfer()
and unreferenced in usbi_handle_transfer_completion(). This transfer could potentially
be freed by any user callback, or is freed by libusb if LIBUSB_TRANSFER_FREE_TRANSFER
is set in the flags. The call to unreference the device uses this potentially freed
memory. Reading the device handle beforehand will prevent this disaster.
|
|
|
|
|
|
|
|
|
| |
For messages received on the hotplug pipe, the message was read via
usbi_read() (ssize_t) and compared against the size of the message
struct (size_t). usbi_read() returns -1 on an error condition, so some
systems can cast the ssize_t to size_t for the comparison, making it
equal to SIZE_MAX and causing the error check condition to incorrectly
evaluate to false.
|
|
|
|
|
|
|
|
|
|
|
| |
handle cancelling active transfers when a device is disconnected
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.
|
|
|
|
| |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Stop pretending that having a separate event handling thread is a bad thing,
specifically delete the "[this] option is not very nice either, but may be
the nicest option available to you if the "proper" approach can not be applied
to your application", which suggests that using poll integration into a main
loop is the one and only "proper" approach.
Instead clearly document there are 2 viable approaches, using a separate
thread, or poll integration into a main loop.
Also stop claiming that libusb does not use threads internally, as with
the new hotplug support this is no longer true.
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>
|
|
|
|
| |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
|
| |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It took me quite a while to debug this, here is a step by step for the race
which I believe is happening in some cases:
1) app calls libusb_submit_transfer
2) libusb_submit_transfer locks itransfer->lock
3) libusb_submit_transfer adds the transfer to the flying list
4) *thread switch*
5) other thread notices POLL_ERR on device fd, calls usbi_handle_disconnect
6) usbi_handle_disconnect find the transfer which is in progress of being
submitted in the flying list
7) usbi_handle_disconnect calls usbi_backend->clear_transfer_priv on the
transfer, this blocks waiting on itransfer->lock
8) *thread switch*
9) libusb_submit_transfer actually tries to submit the transfer now,
calls usbi_backend->submit_transfer, which fails with -ENODEV
10) libusb_submit_transfer *removes* the transfer from the flying list,
unlocks itransfer->lock and returns an error to its caller
11) the caller frees the transfer, meaning the to_cancel pointer in
usbi_handle_disconnect now points to free-ed memory, for extra mayhem
12) *thread switch*
13) usbi_handle_disconnect calls usbi_handle_transfer_completion
14) usbi_handle_transfer_completion tries to remove the transfer from
the flying list *for the 2nd time*
But the first call done from libusb_submit_transfer has already done
this. libusb's list_del looks like this:
static inline void list_del(struct list_head *entry)
{
entry->next->prev = entry->prev;
entry->prev->next = entry->next;
entry->next = entry->prev = NULL;
}
So the first call sets it next and prev to NULL, and then the 2nd call
tries to deref next -> BOOM
For an example backtrace caused by this, see:
https://bugs.freedesktop.org/show_bug.cgi?id=55619#c7
This patch fixes this by letting libusb_submit keep the flying transfers list
locked during submission, so the submission flow changes from:
1) lock flying transfers
add to flying transfers
unlock
2) submit
3) on submission error:
lock flying transfers
remove from flying transfers
unlock
to:
1) lock flying transfers
2) add to flying transfers
3) submit
4) on submission error:
remove from flying transfers
5) unlock
This means that the os backends submit handler now gets called with the
flying transfers lock held! I've looked at all the backends and this should
not be a problem. Only the windows and win-ce backends care about the
flying transfers list at all, and then only in their handle_events handler.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
|
| |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
|
| |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
| |
* fxload sample provenance
* No need for <sys/types.h> in samples as already in libusb.h
* Don't bother about sscanf_s in xusb
* Use HAVE_### and rely on config.h where possible
* Formal inclusion of <winsock.h> in libusb.h for WinCE and WDK
* Cleanup of Windows' config.h
* Avoid ENAMETOOLONG and ENOTEMPTY conflict between errno.h and winsock.h for WinCE
* Additional newlines & braces cleanup
|
|
|
|
|
|
|
|
| |
libusb/io.c:1877:35: warning: implicit conversion loses integer precision: 'long' to 'int' [-Wshorten-64-to-32]
timeout_ms = (tv->tv_sec * 1000) + (tv->tv_usec / 1000);
~ ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
On Mac OS X tv_sec is a __darwin_time_t which is a long, not an int.
|
|
|
|
|
| |
some libusbx include files were included with angle brackets, changed to
quotes. Needed to work better in Xcode project
|
|
|
|
| |
* Closes #70
|
|
|
|
| |
* These files may not be available on all platforms (eg. WinCE)
|
|
|
|
|
|
|
|
| |
* Makes libusb_cancel_transfer not log an error when the cancel fails
with LIBUSB_ERROR_NO_DEVICE, so that apps can properly clean things
up on device disconnect without flooding the console with these errors.
* Also, some devices (Cypress FX) may switch VID:PID on the fly during
firmware upload => reduce severity of the Windows message when that happens.
|
|
|
|
|
|
|
|
| |
* Comparisons between tv_nsec and 1 sec should be >= rather than >,
as we can end up in situations where tv_nsec is exactly 1000000000,
which calls such as timerfd_create() do not accept.
* Issue reported by Sebastian K. See:
https://sourceforge.net/mailarchive/message.php?msg_id=29706972
|
|
|
|
|
| |
* Report errno as well as itimerspec data
* Also reuse the timeout variable set to &transfer->timeout
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Existing code appears disarms the timerfd always, which cancels
pending timeouts as soon as one packet completes.
* This fix moves the disarming of the timerfd to
arm_timerfd_for_next_timeout(), where it is now done conditionally.
It also avoids calling disarm outside of the above call.
* This patch also ensures that all handling of the timerfd is done
under the flying transfers lock.
* Issue reported by Hans de Goede. For more info, see:
https://sourceforge.net/mailarchive/message.php?msg_id=29442693
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
core.c:
* Result of 'malloc' is converted to a pointer of type 'struct libusb_device *',
which is incompatible with sizeof operand type 'void *'
* Memory is never released; potential leak of memory pointed to by 'devs'
* Assigned value is garbage or undefined (due to potentially empty and
uninitialized device list)
descriptor.c:
* Function call argument is an uninitialized value
io.c:
* Call to 'malloc' has an allocation size of 0 bytes
* Branch condition evaluates to a garbage value (due to get_next_timeout
returning a negative error code instead of zero on error)
|
|
|
|
| |
* Also remove extra lines at the end of samples
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Without this change the Windows backend needed to call usbi_fd_notification()
from within the backend's submit_transfer. This can cause deadlock when
attempting to lock the event lock if another thread was processing events on
the just-submitted transfer.
The deadlock comes about as the thread calling libusb_submit_transfer acquires
the transfer mutex before trying to acquire the event lock; this is the other
order of lock acquisition from an event thread handling activity on the just
submitted transfer. This could lead to one of two deadlocks:
1) If the transfer completes while usbi_fd_notification() is waiting for
the event lock and the callback attempts to resubmit the transfer.
2) If the transfer timeout is hit while usbi_fd_notification() is waiting
for the event lock then the attempt to cancel the transfer will deadlock.
This patch fixes both of these deadlocks by having libusb_submit_transfer()
only call usbi_fd_notification() after having released the transfer mutex.
|
| |
|
| |
|
|
|
|
|
| |
* Mentions of 'libusb' in doxygen are changed to 'libusbx'
* Also update copyright notices and remove unneeded EOF LFs
|
|
|
|
|
| |
* Under some cricumstances, LIBUSB_ERROR_NOT_FOUND is an expected
return value for cancel_transfer so printing an error is undesirable.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Some protocols which use USB require an extra zero length data packet
to signal end-of-transfer on bulk endpoints, if the last data packet
is exactly wMaxPacketSize bytes long.
This flag allows applications to inform libusb about this requirement,
so that libusb can handle the issue transparently.
At the moment the new flag is only supported on Linux, and submitting
a transfer with the flag set returns an error at submit time on other
systems. Hopefully implementations will soon follow for other systems.
References #6.
|
|
|
|
|
|
|
|
|
|
|
| |
When libusb was built with timerfd support but used on a system
without timerfd support the library would hang indefinitely on
completion of the first transfer, since timerfd functions were
being called unconditionally and the error returned when timerfd
was not being used caused a confused internal state.
Many thanks to Ivo Smits for looking into the issue, proposing
an initial solution, and helping with testing! Fixes #73.
|
|
|
|
| |
Signed-off-by: Michael Plante <michael.plante@gmail.com>
|
| |
|
|
|
|
| |
References #121.
|
|
|
|
|
|
|
|
|
|
|
| |
The example code and API doc for libusb_handle_events_timeout() could be
interpreted as it being OK to pass a NULL pointer for the tv argument (I
interpreted it like that when I first started coding for libusb).
This patch changes the docs to make it clear that one must always supply
a tv struct to libusb_handle_events_timeout.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
| |
|
|
|
|
|
| |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
[stuge: Note that the old racy functions should be avoided by new code]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The sync API had a race where it would check a condition to know if it
needed to call a libusb_handle_events() function. However, the check
was done outside of the lock that is held while the condition is set,
so another thread could completely serve whatever was needed to make
the condition true between it being checked and the event handler being
called. This situation would be detected after a libusb-internal timeout
of 60 seconds, after which the transfer would be completed without
error, but with significant delay.
Original patch at http://marc.info/?l=libusb-devel&m=127252114815709
Changes by Hans de Goede:
- Renamed the "race-proof" functions from libusb_handle_events*_check()
to libusb_handle_events*_completed()
- Drop r = 0 setting in libusb_handle_events_timeout_completed()
(to make both completed checking cases identical flow wise)
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
[stuge: Simplify libusb_handle_events_timeout() change with a goto]
[pbatard: Fix _handle_events_timeout() and _completed() definitions]
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Any in-flight transfers should properly invalidate their references
to device handles that are being closed. Additionally, they should be
removed from the transfer-in-flight list. This is done with the events
lock held to protect against another thread processing the same transfer.
The events lock is initialized as a recursive mutex, because the device
close code might itself be called while an event is being handled.
Fixes #82.
[stuge: Trivial rework to reduce indenting]
|
|
|
|
|
|
| |
The flags are used to indicate if a cancellation has started, and if
a cancellation has failed because the device is no longer available.
References #82.
|
|
|
|
| |
References #28.
|
|
|
|
|
|
|
|
|
|
|
| |
On Linux, assume nfds_t is always available.
On Darwin, fall back to unsigned int when poll() exists but there
is no nfds_t, such as on Mac OS X before 10.4.
On Windows (both MinGW and Cygwin), always use unsigned int instead
of nfds_t, and don't check for poll.h because we use our own poll()
implementation.
|
|
|
|
|
|
|
|
|
|
|
| |
If transfer->flags indicated that a transfer had a timeout, but no
timeout was actually set, then libusb_get_next_timeout() would look
no further for a timeout, ignoring any transfers later in the list
which had a timeout set.
Since libusb has an internal 60 second timeout this bug could not
cause complete lockup, but it could cause a 60 second timeout even
when a transfer was submitted with a shorter timeout.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Backends set USBI_TRANSFER_OS_HANDLES_TIMEOUT for transfers instead.
Darwin only handles timeouts for bulk and control transfers, so the
backend now sets that flag accordingly, making libusb core handle
timeouts for interrupt and isochronous transfers. Fixes #31.
Signed-off-by: Nathan Hjelm <hjelmn@me.com>
[stuge: rework libusb_get_next_timeout() and enum usbi_transfer_flags]
[stuge: fix typo; set USBI_TRANSFER_TIMED_OUT flag correctly]
|
|
|
|
|
|
|
|
| |
In the libusb_wait_for_event() sample code in the section "Letting other
threads do the work for you" the call to libusb_wait_for_event() was not
updated by commit 1df713d622ab4f0b03aad72d903ac7beb8fb3b90, which added
the libusb_context *ctx parameter to the function, so the sample code
was broken until now.
|
|
|
|
|
|
| |
Windows does not have numerical file descriptors but does have the
concept of event sources. Exposing these event sources will require
some careful thought and design, to be completed later.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Under Windows, a variety of compilers and configurations are available,
meaning that the manner of parameter passing (e.g. registers vs stack)
can vary.
Match the Windows API calling convention and document this appropriately.
This calling convention will be used regardless of the configuration of
the user's development platform.
The only user-level complication is that all functions used as libusb
callbacks must use the same calling convention as libusb. The
LIBUSB_CALL macro is provided to make this easy.
Signed-off-by: Michael Plante <michael.plante@gmail.com>
Signed-off-by: Pete Batard <pbatard@gmail.com>
[dsd: slight change of strategy, add documentation]
|
|
|
|
|
|
| |
Via Cygwin/MinGW, libusb now has windows support.
Thanks to contributors: Michael Plante, Orin Eman, Peter Stuge,
Stephan Meyer, Xiaofan Chen.
|