summaryrefslogtreecommitdiff
path: root/libusb/io.c
Commit message (Collapse)AuthorAgeFilesLines
* Core: Fix potential segfault caused by using freed memoryChris Dickens2013-08-071-1/+2
| | | | | | | | 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.
* Core: correctly check usbi_read() returned valueChris Dickens2013-08-021-2/+2
| | | | | | | | | 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.
* keep a reference to the device for each active transfer and let the backend ↵Nathan Hjelm2013-07-301-0/+3
| | | | | | | | | | | 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.
* Documentation: add an Using an event handling thread sectionHans de Goede2013-07-051-3/+62
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* Documentation: explain the 2 main viable event handling approachesHans de Goede2013-07-051-33/+30
| | | | | | | | | | | | | | | | 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>
* hotplug: Give the usbi_hotplug_match* functions a context parameterHans de Goede2013-07-051-1/+1
| | | | | | | 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>
* POSIX: Move setting of pipes to non-blocking into usbi_pipeToby Gray2013-05-281-6/+0
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* core: Fix handle_events return code on hotplug pipe read errorHans de Goede2013-05-171-1/+1
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* usbi_handle_disconnect: Fix race condition leading to double completionHans de Goede2013-05-161-15/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* usbi_handle_disconnect: Add some debugging wrt cancelled transfersHans de Goede2013-05-161-0/+3
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* core: Improve error / debug messages for hotplug pipe handlingHans de Goede2013-05-161-0/+4
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* Add some editor meta-comments for proper tab usageNathan Hjelm2013-05-151-0/+1
| | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com>
* Add hotplug support.Nathan Hjelm2013-05-151-4/+51
| | | | | | | | | | | | | | | | | | | | | | | | 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>
* Misc: Simplify includes and misc. cleanupPete Batard2013-02-271-3/+0
| | | | | | | | | | | * 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
* Core: Fix compiler warningLudovic Rousseau2013-02-151-1/+1
| | | | | | | | 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.
* Use "" instead of <> for internal includesSean McBride2013-02-151-1/+1
| | | | | some libusbx include files were included with angle brackets, changed to quotes. Needed to work better in Xcode project
* Core: Fix warning implicit conversion changes signednessLudovic Rousseau2013-01-291-4/+5
| | | | * Closes #70
* Core: Use HAVE_SYS_TYPES_H and HAVE_SIGNAL_HPete Batard2013-01-231-1/+4
| | | | * These files may not be available on all platforms (eg. WinCE)
* All: Avoid polluting errors reported on device disconnectHans de Goede2012-09-131-1/+2
| | | | | | | | * 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.
* Core: Handle >= 1 second transfer timeout in libusb_submit_transfer()Peter Stuge2012-08-221-4/+3
| | | | | | | | * 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
* Core: Improve instrumentation of timerfd_settime failuresPete Batard2012-08-121-2/+3
| | | | | * Report errno as well as itimerspec data * Also reuse the timeout variable set to &transfer->timeout
* Core: Fix unconditional disarming of timerfdPete Batard2012-08-041-91/+82
| | | | | | | | | | | | * 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
* All: Replace malloc+memset with callocDavidlohr Bueso2012-07-131-2/+1
|
* Core: Fix Clang warningsPete Batard2012-06-131-3/+4
| | | | | | | | | | | | | | | 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)
* Misc: Ensure all sources are UTF-8Pete Batard2012-05-231-2/+2
| | | | * Also remove extra lines at the end of samples
* Windows: Fix deadlock in backend when submitting transfers.Toby Gray2012-05-031-0/+4
| | | | | | | | | | | | | | | | | | | | | 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.
* Core: Add debug message with callback address on completed transferPeter Stuge2012-04-201-0/+1
|
* Misc: Fix missing libsub's -> libusbx's from previous patchesPete Batard2012-04-031-27/+27
|
* Misc: Rebrand to libusbxPete Batard2012-04-031-92/+92
| | | | | * Mentions of 'libusb' in doxygen are changed to 'libusbx' * Also update copyright notices and remove unneeded EOF LFs
* Linux: Don't print errors when cancel_transfer fails with NOT_FOUNDHans de Goede2012-03-261-2/+5
| | | | | * Under some cricumstances, LIBUSB_ERROR_NOT_FOUND is an expected return value for cancel_transfer so printing an error is undesirable.
* Add LIBUSB_TRANSFER_ADD_ZERO_PACKET flag to indicate need for ZLPPeter Stuge2012-02-221-0/+2
| | | | | | | | | | | | | | | 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.
* Do not call timerfd functions when timerfd is not being usedPeter Stuge2012-02-131-5/+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.
* Windows: Output an error message on calls to libusb_get_pollfds()Pete Batard2012-02-081-0/+2
| | | | Signed-off-by: Michael Plante <michael.plante@gmail.com>
* io.c: Fix comment since pthreads isn't the only threading libusb usesPete Batard2012-02-081-1/+1
|
* Fix unused variable warnings when without timerfd and/or when on DarwinSean McBride2011-10-171-0/+3
| | | | References #121.
* Docs: Clarify that libusb_handle_events_timeout() tv param can't be NULLHans de Goede2011-10-171-9/+9
| | | | | | | | | | | 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>
* Fix typos in introductory documentationSebastian Pipping2011-09-221-2/+2
|
* Document libusb_handle_events_completed() and _timeout_completed()Hans de Goede2011-09-221-6/+89
| | | | | Signed-off-by: Hans de Goede <hdegoede@redhat.com> [stuge: Note that the old racy functions should be avoided by new code]
* Fix #56 race condition causing delayed completion of sync transfersGraeme Gill2011-09-221-5/+28
| | | | | | | | | | | | | | | | | | | | | | | 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]
* Fix #64 use of reserved identifiers throughout libusbNathan Hjelm2011-09-221-9/+9
|
* Clean up in-flight transfers and device handle when closing a deviceVitali Lovich2011-07-241-1/+1
| | | | | | | | | | | | 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]
* Add USBI_TRANSFER_CANCELLING and _DEVICE_DISAPPEARED status flagsVitali Lovich2011-07-241-1/+8
| | | | | | 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.
* io.c: Fix clang analyzer warning about unused variableSean McBride2011-06-131-0/+2
| | | | References #28.
* configure.ac: Check for poll.h, and for nfds_t on DarwinPeter Stuge2011-06-131-1/+1
| | | | | | | | | | | 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.
* Core: libusb_get_next_timeout() must consider all flying transfersPeter Stuge2011-06-131-7/+5
| | | | | | | | | | | 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.
* Remove USBI_OS_HANDLES_TIMEOUT and fix int/isoc timeouts on DarwinNathan Hjelm2010-11-261-23/+7
| | | | | | | | | | | | 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]
* Add missing argument to libusb_wait_for_event() documentation, fix #55Ludovic Rousseau2010-10-161-1/+1
| | | | | | | | 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: Make libusb_pollfd() return errorPete Batard2010-09-191-3/+14
| | | | | | 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.
* Introduced calling convention (for Windows)Pete Batard2010-08-231-19/+22
| | | | | | | | | | | | | | | | | | 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]
* Add Windows supportPete Batard2010-07-271-2/+0
| | | | | | Via Cygwin/MinGW, libusb now has windows support. Thanks to contributors: Michael Plante, Orin Eman, Peter Stuge, Stephan Meyer, Xiaofan Chen.