summaryrefslogtreecommitdiff
path: root/libusb/io.c
Commit message (Collapse)AuthorAgeFilesLines
* Fix #1263 by acquiring the waiters lock while calling transfer callbacks and ↵Niklas Gürtler2023-04-121-1/+4
| | | | | | | | swapping the order of operations in sync_transfer_cb Fixes #1267, #1263 Signed-off-by: Nathan Hjelm <hjelmn@google.com>
* Fix most -Wpedantic warningsTormod Volden2023-01-211-5/+6
| | | | | | On Linux and gcc 12.2 at least. Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
* docs: Clear endpoint halt issued after cancellation only for macOS < 10.5Martin Ling2023-01-061-15/+17
| | | | | | | | | | Also remove comment about possible endpoint halt, which seems not correct, as discussed in issue #1110. References #1110 Closes #1117 Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
* darwin: Do not clear device data toggle on macOS 10.5 or newerNathan Hjelm2023-01-061-3/+7
| | | | | | | | | | | | Historically Mac OS X always cleared the data toggle on the host side. For consistency, libusb has been calling ClearPipeStallBothEnds to also clear the device side toggle. Newer versions of the IOUSBLib do not clear the host side toggle so there is no need to make this call. Additionally, some buggy devices may fail to correctly implement clearing the data toggle. Signed-off-by: Nathan Hjelm <hjelmn@google.com> [Tormod: Return result from AbortPipe] Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
* Doxygen: Add references to LIBUSB_ERROR codesLudovic Rousseau2022-06-261-9/+9
| | | | Signed-off-by: Ludovic Rousseau <ludovic.rousseau@free.fr>
* darwin: Document OS-specific behaviour of libusb_cancel_transferMartin Ling2022-04-091-0/+20
| | | | | | | | | | | | | The behaviour of libusb_cancel_transfer is different on Darwin: - Cancellation cancels all transfers on the same endpoint. - A ClearFeature(ENDPOINT_HALT) request is sent after cancellation. This documents both differences and their implications. Fixes #1110 Closes #1121
* io: Track device in usbi_transferBenjamin Berg2022-03-161-8/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | transfer->dev_handle currently has the behaviour that it will be unset if the device is closed. The sync API uses this fact to catch an error case. In other cases, transfer->dev_handle will keep its value, which means that if the transfer lives longer than the device handle, the pointer becomes invalid. The transfer does however keep a reference to the device, which owns the pointer to the context. As such, we can track this reference internal to the transfer, and it is set while the transfer is in-flight. With this, switch the logging infrastructure to use itransfer->dev->ctx while checking that itransfer->dev is non-NULL. Note that this was a regression caused by 6cae9c6 ("core: update usbi_dbg to take the context as an argument"), specifically when resolving the context while freeing a transfer after closing a device. Note that the transfer will now keep a reference to the device until it is free'ed. This allows it to use the correct context for logging even in libusb_free_transfer. The alternative to all this would be to just explicitly pass NULL to the log handler in libusb_free_transfer. Fixes #1038 Closes #1073
* Fix various typos in docs/commentsluz paz2021-10-311-1/+1
| | | | | | Found via `codespell -q 3` Closes #1015
* Fix comment typosSean McBride2021-09-231-1/+1
| | | | References #981
* core: update usbi_dbg to take the context as an argumentNathan Hjelm2021-07-211-39/+39
| | | | | | | | | | | | | This commit fixes a performance issue caused by the disconnection of the first context allocated from the default context. usbi_dbg now takes the explicit context instead of relying on the default context (which may not exist) in most cases. All call sites have been updated to pass the context or explicitly pass NULL if the context is not available. We should actively discourage using NULL as the context in the future and patch all call sites to always pass the context. Fixes #951 Signed-off-by: Nathan Hjelm <hjelmn@google.com>
* core: Refactor initialization and how the default context is handledChris Dickens2021-06-021-15/+11
| | | | | | | | | | | | | | | | | | | Highlights for this change: - usbi_default_context is only set if libusb_init() is called with NULL. - All hotplug related functionality (e.g. initialization, processing) has been moved to hotplug.c - Backends are simplified by removing initialization mutexes. Mutual exclusion between init()/exit() is provided by default_context_lock. - Make hotplug types and functions part of libusbi.h with the common usbi_ prefixes (removes hotplug.h). Addresses issue highlighted in #855 Closes #856 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com> Signed-off-by: Nathan Hjelm <hjelmn@google.com>
* core: Iterate over completed transfers using the correct list nodeChris Dickens2020-10-151-1/+1
| | | | | | | | | | Commit 006ca0fbaa ("Guard against getting stuck while handling events") caused a regression using the wrong list node when iterating a list. Fix this by introducing and using an alternate for_each iterator. Closes #796 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Split usbi_clock_gettime() into two separate functionsChris Dickens2020-09-131-51/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | Most of the library only uses the monotonic clock. In fact, the only use of the realtime clock is to implement the POSIX version of usbi_cond_timedwait(). Now that Windows can no longer use the POSIX thread abstraction, there is no need for Windows to implement a means of reading the realtime clock. This change replaces usbi_clock_gettime() with usbi_get_monotonic_time() and usbi_get_real_time(). When clock_gettime() is available, both functions are implemented as simple inline calls, otherwise the backend must provide a definition for usbi_get_monotonic_time() *AND* usbi_get_real_time() iff the platform is POSIX. Reading the clocks is also never expected to fail. In practice, if it ever did there would be much more than libusb that would not function correctly. The new functions therefore have no return value, thus allowing the callers to assume success and remove a bunch of error handling code. The clock_gettime() wrappers have a simple error check that is only enforced in debug builds. This change also makes it unnecessary to check for and use clock_gettime() on Windows, so remove it and always provide usbi_get_monotonic_time(). Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Add validation to timeval parametersChris Dickens2020-09-131-5/+19
| | | | | | | | | | | | Prior to this change, the timeval structures provided by users did not go through any type of validation, therefore an invalid timeval would result in potentially unclear or confusing errors when used later on. Add checks to the core API functions that accept timevals and return LIBUSB_ERROR_INVALID_PARAM if the timeval is not valid. While at it, add some macro definitions to avoid magic numbers. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Simplify thread abstractions and add debug checksChris Dickens2020-09-131-5/+4
| | | | | | | | | | | | | | | | | | | The POSIX thread mutex initialization function can potentially fail, but in practice this is unlikely to occur. There is also inconsistent use of the result of the mutex initialization within the library. The result is only checked for mutexes in the libusb_device and libusb_device_handle structures but is ignored in all other cases. Simplify the mutex initialization function by changing the abstraction's wrapper to a void function, much like all the other functions that already exist. To that end, introduce macros for the abstractions that will check the return value on debug builds. Also remove the dependence on the core library needing errno.h to translate errors from usbi_cond_timedwait(). The abstraction will convert the implementation-specific error codes to LIBUSB_ERROR values. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* build: Merge events and threads into single platform abstractionChris Dickens2020-09-121-5/+5
| | | | | | | | | | | | | | The split between events and threads abstractions is unnecessary. Simplify the library by merging the two into a "platform" abstraction. The only meaningful change is that Cygwin builds will no longer use the POSIX threads abstraction but will instead use the native Windows one. The downside to doing this is that the dpfp_threaded example program will no longer be available on Cygwin builds. This should be fine, and future work will make dpfp_threaded available for all forms of Windows build systems. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* Guard against getting stuck while handling eventsChris Dickens2020-09-121-7/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | Alba Mendez (user mildsunrise) reports that a thread can get stuck at a specific point while handling events, thus preventing other events from being handled. This change addresses two such points in the code: 1) When processing completed transfers in handle_event_trigger(), the function wll loop for as long as the completed_transfers list is not empty. Since the event data lock is released and reacquired for each completed transfer, it is possible for the completed_transfers list to never be emptied. Address this by cutting the list and only process the transfers that have completed at that point in time. 2) When processing events, the Linux backend will reap transfers for each device that indicates activity until the reap fails (either because there are no completed transfers or some other error occurs). It is possible for transfers to be reaped at a rate slower than that at which they are completing, thus preventing the loop from exiting. Address this by limiting the number of transfers reaped for each device to 25 for every call to the Linux backend's handle_events() function. Closes #780 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Ensure that reported event bits are initializedChris Dickens2020-08-241-0/+2
| | | | | | Closes #774 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* Fix typos detected by codespell and manual inspectionChris Dickens2020-08-181-9/+9
| | | | Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* Documentation: Specify the constraint of the 'completed' parameterChris Dickens2020-08-181-0/+5
| | | | | | Closes #482 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* Documentation: Add a note regarding the execution context of callbacksChris Dickens2020-08-181-1/+8
| | | | | | | | | | Make it more clear that callbacks are only called when libusb_handle_events() is called and that all callbacks will be called on the same thread calling that function. Closes #349 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* Documentation: Add details regarding timeouts and partial transfer of dataChris Dickens2020-08-181-2/+33
| | | | | | Closes #348 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* Documentation: Add section regarding transfer length limitationsChris Dickens2020-08-181-6/+13
| | | | | | Closes #204 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Optimize check for pending eventsChris Dickens2020-08-121-22/+31
| | | | | | | | | | Prior to this commit, a check for whether any events are pending involved checking four different variables within the context. Optimize this by using multiple bits within a single unsigned integer to represent all the possible events that could be pending. This reduces the check for whether any events are pending to a single load. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Introduce platform events abstractionChris Dickens2020-08-121-313/+222
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The way in which system handles or resources are represented differs greatly between Unix-like operating systems and Windows. Ever since Windows support was added to libusb, Windows been emulating principles of Unix-like operating systems such as file descriptors and poll(). This commit introduces an abstraction layer that completely removes the need to perform any emulation. Fundamentally there are three things that each platform provides to libusb: 1) A signallable event 2) A timer (not required, but useful) 3) A means to wait for event sources such as the above to be triggered The POSIX abstraction for Unix-like operating systems uses file descriptors as the "handles" to the underlying system resources. The signallable event is implemented using a pipe, the timer as a timerfd (where supported) and the poll() system call is used to wait for events. The Windows abstraction uses native HANDLEs as the "handles" to the underlying system resources. The signallable event is implemented using a manual-reset event, the timer as a manual-reset waitable timer, and the WaitForMultipleObjects() system call is used to wait for events. Closes #252 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Introduce list iteration helpersChris Dickens2020-08-101-12/+16
| | | | | | | | | | | | | | | | | | | The syntax for traversing over lists is somewhat cluttered. It could be made much better with the use of the 'typeof' keyword, but unfortunately this is not universally supported by all compilers. We can, however, improve the situation by introducing some macros for the common cases. To that end, this commit introduces a number of 'for_each' macros that iterate over a specific linked list. Current syntax: list_for_each_entry(itransfer, &ctx->flying_transfers, list, struct usbi_transfer) New syntax: for_each_transfer(ctx, itransfer) Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Fix some minor inconsistencies in API and codingChris Dickens2020-04-271-4/+3
| | | | | | | | | | | | | | | | | | | | | All of the API functions should take the typedef'ed versions of the opaque libusb structures, but some recent additions to the API did not follow this convention. Fix this by making the changes to the declarations and definitions of the functions. Make the placement of the asterisk in pointer variable declarations consistent (always with the variable name, not the type). Remove some unnecessary casts and initializations relating to dynamically allocated memory. While at it, make casts within the core library consistent in style with no space after the closing parenthesis of the cast. Most of the core already used this style. When using the 'sizeof' operator, dereference the pointer instead of using the type. Most of the core was already doing this, so fix up the few places that weren't. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* build: Enable additional build errors and warningsChris Dickens2020-03-301-0/+1
| | | | | | | | | | | Help catch more errors by enabling additional build errors and warnings. Address some of the warnings seen with these new flags, including moving the libusb_transfer structure back out of the usbi_transfer structure to address 'warning: invalid use of structure with flexible array member'. Apparently a structure ending with a flexible array member is not okay with the compiler as the last member within another structure. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Kill the OS_* definitions and use in the source codeChris Dickens2020-03-271-1/+1
| | | | | | | These symbols are no longer necessary for the source code since commit cad7d0edd9 ("core: Kill usbi_os_backend structure definition madness"). Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Fix return value of usbi_clock_gettime()Chris Dickens2020-03-161-3/+5
| | | | | | | | | | | In most cases, usbi_clock_gettime() will map to the standard library's clock_gettime() function. The semantics of this function are that it returns -1 upon failure with the error code available in the errno variable. The backends that need to implement this function should follow the same semantics, and the return value of usbi_clock_gettime() should not be directly propagated upwards. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Move parameter validation from backend to coreChris Dickens2020-03-161-0/+2
| | | | | | | | | | | | | | Some functions (e.g. libusb_set_interface_alt_setting()) do not perform sufficient parameter validation, leaving the burden on the backend to catch invalid user input. Much of this validation is common across all backends, yet not every backend implemented it. Fix this by moving parameter validation to the core library functions. This is also a good opportunity to remove the redundant 'num_configurations' field from the libusb_device structure. The value of this field is already contained in the 'device_descriptor' member. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Kill usbi_backend.clock_gettime() functionChris Dickens2020-03-151-3/+3
| | | | | | | | | | | | | | | | | | Out of all the backends supported by libusb, only two need to provide an implementation of the clock_gettime() function. Windows completely lacks such a function and versions of Mac OS prior to 10.12 do not provide it. In all other cases the backend simply ends up calling the C library's clock_gettime() function. Let's optimize for the common case and check for the availability of clock_gettime() during configure. If available, we will just call it directly from any part of the library that needs it. If not available, the backend is required to provide an implementation of usbi_clock_gettime() that matches the current requirements. Closes #685 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Switch usbi_transfer to store timeout as timespecChris Dickens2020-03-051-43/+32
| | | | | | | | | | | | | | | | | The transfer timeout is structured around time values provided by the clock_gettime() function. This function uses a timespec structure, but the usbi_transfer structure was storing its calculated timeout in a timeval structure. This mismatch introduces extra work when checking for transfer timeouts as there must be a conversion between these two structures. Eliminate this by storing the calculated timeout as a timespec, thus allowing direct comparison. Note that a conversion to a timeval is still necessary in the libusb_get_next_timeout() function because the public API uses a timeval structure, but this is now the only place where such a conversion is done. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Introduce accessor functions for structure private dataChris Dickens2020-02-261-2/+2
| | | | | | | | | | | | | | | | | | | | | The backend private data for the internal library structures has been accessed through a zero-length os_priv array of type unsigned char. This approach had two particular disadvantages: 1) A special attribute was needed on the 'os_priv' member to ensure that the field was properly aligned to a natural pointer alignment. The support needed for this is not available in every compiler. 2) Each access to the private data areas required an explicit cast from unsigned char to the type required by the backend. This change reworks the way the private data is accessed by the backends. New accessor functions return the private data as a void pointer type, removing the need for an explicit cast (except for Haiku, which is C++). The special alignment attribute trickery is also replaced by simple pointer arithmetic. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Optimize the memory layout of the transfer structureChris Dickens2020-02-261-10/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | Prior to this commit, the memory layout of the transfer structure was as follows: ------------------------------------------------------ | usbi_transfer | libusb_transfer [variable] | os_priv | ------------------------------------------------------ With this layout, accessing the os_priv area requires calculating the size of the area used by the libusb_transfer, which varies based on the number of iso packets allocated for the transfer. This commit changes the memory layout of the transfer structure to the following: ------------------------------------------------------ | os_priv | usbi_transfer | libusb_transfer [variable] | ------------------------------------------------------ Having the os_priv in a fixed position relative to the usbi_transfer allows for constant-time access with the added benefit of not allowing the user to corrupt the data by accessing elements of the libusb_transfer structure that are out-of-bounds. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Use a consistent variable name for usbi_transfer structuresChris Dickens2020-02-261-43/+43
| | | | | | | | | | Most places in the library use the name 'itransfer' when referring to a usbi_transfer structure. This is helpful to distinguish between the public libusb_transfer structure and the internal structure. Fix up the few places that don't follow this convention so that it is consistent across the entire library. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* linux_usbfs: Drop support for kernel versions earlier than 2.6.32Chris Dickens2020-01-261-2/+1
| | | | | | | | | | | | | | | The Linux backend plays lots of games to try and work with older versions of the kernel that do not have certain features. Lets simplify the backend by requiring at least 2.6.32 to use libusb. The only thing remaining that still requires explicit version checking is the maximum iso frame packet size. Anything running 2.6.32 or later is sure to have a functional monotonic clock, so this change also allows the removal of the get_timerfd_clock() function from the backend as well as the check for a functional monotonic clock during initialization. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Convert internal macros to static inline functionsChris Dickens2020-01-251-16/+22
| | | | | | | | | | | | Older versions of the Visual Studio compiler are picky about macros constructed with the 'do { ... } while (0)' construct. Convert these internal ones to static inline functions. The result is functionally equivalent but gets us type checking and a bit more readability. Also address some compiler warnings due to some header files that are being included in a different order than before. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* configure.ac: Cleanup and refactoringChris Dickens2020-01-241-12/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Make the formatting consistent across the entire file. In particular: - Always quote strings whose values are derived - Use tabs consistently - Wrap all arguments with square brackets Replace the use of '-a' with '&&' to be more portable. Rearrange some of the feature checks to be conditional upon the platform or backend. For example, there is no need to check for nfds_t on Windows because poll() doesn't exist there. Similarly we now only check for timerfd on Linux and Solaris. This translates into slightly faster configure times. Explicitly define tokens for both the poll and thread implementations. This makes the preprocessor conditionals much nicer since it is not necessary to enumerate all possible OS_* tokens. Also replace POLL_NFDS_TYPE with a proper typedef that is based on the availability of the nfds_t type. Migrate to config definition names that are more consistent with autoconf. The check for timerfd actually verifies the presence of the library function instead of just the header definitions, and the token USBI_TIMERFD_AVAILABLE is now HAVE_TIMERFD. Similarly the check for syslog results in a definition of HAVE_SYSLOG. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* Misc: Trim and consolidate header file usageChris Dickens2020-01-241-13/+3
| | | | | | | | | | | | | Refactor libusbi.h to include the set of common header files needed by every main source file in the library and change these source files to include libusbi.h first, followed by any non-common headers. Including libusbi.h first ensures that the config definitions are pulled in and will eliminate redundant includes in the individual sources files. Also clean up some whitespace errors and remove unnecessary definitions in the manually generated config.h files. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: Make style of debug messages with errno consistent across libraryChris Dickens2020-01-241-4/+3
| | | | Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* Windows: Improve poll abstractionChris Dickens2020-01-221-8/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 395e5a8a6f ("windows: remove total fds (256) limitations") and commit c730a8410c ("windows: workaround WaitForMultipleObjects max 64 events limitation.") lifted some hard-coded limits in the number of HANDLEs that can be used within the library. This change improves on these changes to make them more efficient. A bitmap has been added to provide an efficient lookup mechanism for located unused file descriptor indices. This avoids the O(n) lookup time for traversing the entire fd_table. This bitmap is dynamically resized along with the fd_table. The incremental size of the fd_table has been reduced from 256 to 64. The vast majority of applications won't need to use 256 HANDLEs, so we can optimize memory usage a bit. Commit fb864b7cde ("fix windows crash when multi-thread do sync transfer") added usbi_inc_fds_ref() and usbi_dec_fds_ref() functions to work around a reference count issue. Remove these functions and change the implementation of usbi_poll() to take a reference to each file descriptor upon entry and drop the references when returning. If the application experiences any kind of crash, there is a problem elsewhere. Finally, make the thread executing usbi_poll() take part in the waiting. The original implementation had this thread simply waiting on a single event while separate threads waited on the HANDLEs. Now this thread will wait on MAXIMUM_WAIT_OBJECTS - 1 HANDLEs, thereby reducing the number of threads that are created. Additionally there is now only a single event object that is shared amongst all waiting threads. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: fix build warning on newer versions of gccGreg Kroah-Hartman2020-01-131-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | When building libusb on a "newer" version of gcc (9.2), a lot of warnings are thrown about zero-length messages as being part of a format string. An example of this is: descriptor.c:546:11: warning: zero-length gnu_printf format string [-Wformat-zero-length] 546 | usbi_dbg(""); | ^~ Fix this up by replacing all calls of: usbi_dbg(""); with usbi_dbg(" "); as obviously we still want to keep the implicit tracing message in the log. Closes #674 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
* core: protect against changes to the pollfd list during handle_eventsNathan Hjelm2019-08-141-1/+31
| | | | | | | | | | | | | | It is possible a file descriptor to be removed due to a close and the same file descriptor value to be added during the same event loop. This can cause the backend to get a stale revent and incorrectly remove the file descriptor. This commit addresses the issue by delaying the actual removal of the ipollfds entry until just before the backend handle_events is called. handle_events then goes through the list of closed fds and clears out the revents associated with the closed file descriptor. Signed-off-by: Nathan Hjelm <hjelmn@google.com>
* Fix some -Wformat warnings.Josh Gao2019-07-071-1/+1
| | | | | | Closes #561 Signed-off-by: Nathan Hjelm <hjelmn@me.com>
* mingw fixRipleyTom2019-07-071-0/+1
| | | | | | Closes #566 Signed-off-by: Nathan Hjelm <hjelmn@me.com>
* solaris: Fix crash on closing libusb handleAlexander Pyhalov2019-04-041-8/+12
| | | | | | | | | | | | | libusb_close() can interrupt transfer to device, setting dev_handle to NULL. In this case all async requests should exit gracefully. Also usbi_signal_transfer_completion() can dereference dev_handle in this case. Closes #434 Signed-off-by: Nathan Hjelm <hjelmn@me.com>
* fix windows crash when multi-thread do sync transferFrank Li2019-04-041-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | fun() { libusb_open() ... sync transfer libusb_close() } two thread call fun infininately. to speed up crash, enable application verifier below 20 cycle, assert(fd!=NULL) happen at check_pollfds below 100 cycle, crash at pollable_fd->overlappend in winusb_get_overlapped result with this fix, success fun over 1000 cycles in handle_events usbi_mutex_lock() fds = ctx->pollfds nfds = ctx->pollfds_cnt; usbi_mutex_unclock() usbi_poll() callback. usbi poll is not in mutex. pollfds may be change by usbi_add_pollfd and usbi_remove_pollfd. Although usbi_add_pollfd and usbi_remove_pollfd hold mutex, but usbi_poll and callback is not in protext of mutex. windows use fd as index of fb_table. fb_table may changed by usbi_remove_pollfd. the map between fd and internal file_descriptor may be wrong. this patch added ref count for file_descriptor, only free file_desciptor and remove it from fb_table when ref count is 0. ref count will be increase when fds copy with mutex lock. so fd always index validate file_descriptor. ref count will be descress before return from handle_events. the file_descriptor can be free safely at this time. Closes #521 Signed-off-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Nathan Hjelm <hjelmn@me.com>
* Fixed many compiler warnings about sign and size mismatchSean McBride2019-01-301-5/+11
| | | | | | | | | | - added various casts - added some asserts where the casts made assumptions - enabled additional warnings in Xcode project (especially -Wshorten-64-to-32) Closes #509 Signed-off-by: Nathan Hjelm <hjelmn@me.com>
* fix race condition at event_handlesFrank Li2019-01-301-2/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | event_handles supposed just run at a thread. There are re-entry check at begin. 1: if (usbi_handling_events(ctx)) 2: return LIBUSB_ERROR_BUSY; 3: usbi_stat_event_handle(ctx); this code is hold any lock it is possible two thread check 1 at the same time, then go through to 3. So two threads will run event_handles. above 3 line code should hold event_data_lock to avoid above race condition. 1: usbi_mutex_lock($ctx->event_data_lock); 2: r = 0; 3: if (usbi_handling_events(ctx)) 4: r = LIBUSB_ERROR_BUSY; 5: else 6: usbi_start_event_handling(ctx); 7: usbi_mutex_unlock($ctx->event_data_lock); 8: if(r) 9: return r; check and set in an atomic operations. Closes #520 Signed-off-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Nathan Hjelm <hjelmn@me.com>