| Index: third_party/libusb/src/libusb/io.c
|
| diff --git a/third_party/libusb/src/libusb/io.c b/third_party/libusb/src/libusb/io.c
|
| index e9bd312c8cc2d624b7c8826461bb1338162fd4b7..4368b9945740d9f1012e8e4bf1c3c7a4f3f70dd6 100644
|
| --- a/third_party/libusb/src/libusb/io.c
|
| +++ b/third_party/libusb/src/libusb/io.c
|
| @@ -1,7 +1,8 @@
|
| +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
|
| /*
|
| - * I/O functions for libusb
|
| - * Copyright (C) 2007-2009 Daniel Drake <dsd@gentoo.org>
|
| - * Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
|
| + * I/O functions for libusbx
|
| + * Copyright © 2007-2009 Daniel Drake <dsd@gentoo.org>
|
| + * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
|
| *
|
| * This library is free software; you can redistribute it and/or
|
| * modify it under the terms of the GNU Lesser General Public
|
| @@ -18,33 +19,34 @@
|
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| */
|
|
|
| -#include <config.h>
|
| +#include "config.h"
|
| #include <errno.h>
|
| -#include <signal.h>
|
| #include <stdint.h>
|
| #include <stdlib.h>
|
| #include <string.h>
|
| #include <time.h>
|
| -
|
| +#ifdef HAVE_SIGNAL_H
|
| +#include <signal.h>
|
| +#endif
|
| #ifdef HAVE_SYS_TIME_H
|
| #include <sys/time.h>
|
| #endif
|
| -
|
| #ifdef USBI_TIMERFD_AVAILABLE
|
| #include <sys/timerfd.h>
|
| #endif
|
|
|
| #include "libusbi.h"
|
| +#include "hotplug.h"
|
|
|
| /**
|
| * \page io Synchronous and asynchronous device I/O
|
| *
|
| * \section intro Introduction
|
| *
|
| - * If you're using libusb in your application, you're probably wanting to
|
| + * If you're using libusbx in your application, you're probably wanting to
|
| * perform I/O with devices - you want to perform USB data transfers.
|
| *
|
| - * libusb offers two separate interfaces for device I/O. This page aims to
|
| + * libusbx offers two separate interfaces for device I/O. This page aims to
|
| * introduce the two in order to help you decide which one is more suitable
|
| * for your application. You can also choose to use both interfaces in your
|
| * application by considering each transfer on a case-by-case basis.
|
| @@ -74,7 +76,7 @@
|
| * Data will arrive when the button is pressed by the user, which is
|
| * potentially hours later.
|
| *
|
| - * libusb offers both a synchronous and an asynchronous interface to performing
|
| + * libusbx offers both a synchronous and an asynchronous interface to performing
|
| * USB transfers. The main difference is that the synchronous interface
|
| * combines both steps indicated above into a single function call, whereas
|
| * the asynchronous interface separates them.
|
| @@ -129,9 +131,9 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| * above.
|
| *
|
| * Instead of providing which functions that block until the I/O has complete,
|
| - * libusb's asynchronous interface presents non-blocking functions which
|
| + * libusbx's asynchronous interface presents non-blocking functions which
|
| * begin a transfer and then return immediately. Your application passes a
|
| - * callback function pointer to this non-blocking function, which libusb will
|
| + * callback function pointer to this non-blocking function, which libusbx will
|
| * call with the results of the transaction when it has completed.
|
| *
|
| * Transfers which have been submitted through the non-blocking functions
|
| @@ -142,12 +144,12 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| * to use threads.
|
| *
|
| * This added flexibility does come with some complications though:
|
| - * - In the interest of being a lightweight library, libusb does not create
|
| + * - In the interest of being a lightweight library, libusbx does not create
|
| * threads and can only operate when your application is calling into it. Your
|
| - * application must call into libusb from it's main loop when events are ready
|
| - * to be handled, or you must use some other scheme to allow libusb to
|
| + * application must call into libusbx from it's main loop when events are ready
|
| + * to be handled, or you must use some other scheme to allow libusbx to
|
| * undertake whatever work needs to be done.
|
| - * - libusb also needs to be called into at certain fixed points in time in
|
| + * - libusbx also needs to be called into at certain fixed points in time in
|
| * order to accurately handle transfer timeouts.
|
| * - Memory handling becomes more complex. You cannot use stack memory unless
|
| * the function with that stack is guaranteed not to return until the transfer
|
| @@ -157,7 +159,7 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| * results are handled. This becomes particularly obvious when you want to
|
| * submit a second transfer based on the results of an earlier transfer.
|
| *
|
| - * Internally, libusb's synchronous interface is expressed in terms of function
|
| + * Internally, libusbx's synchronous interface is expressed in terms of function
|
| * calls to the asynchronous interface.
|
| *
|
| * For details on how to use the asynchronous API, see the
|
| @@ -174,25 +176,25 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| * constraints on packet size defined by endpoint descriptors. The host must
|
| * not send data payloads larger than the endpoint's maximum packet size.
|
| *
|
| - * libusb and the underlying OS abstract out the packet concept, allowing you
|
| + * libusbx and the underlying OS abstract out the packet concept, allowing you
|
| * to request transfers of any size. Internally, the request will be divided
|
| * up into correctly-sized packets. You do not have to be concerned with
|
| * packet sizes, but there is one exception when considering overflows.
|
| *
|
| * \section overflow Bulk/interrupt transfer overflows
|
| *
|
| - * When requesting data on a bulk endpoint, libusb requires you to supply a
|
| - * buffer and the maximum number of bytes of data that libusb can put in that
|
| + * When requesting data on a bulk endpoint, libusbx requires you to supply a
|
| + * buffer and the maximum number of bytes of data that libusbx can put in that
|
| * buffer. However, the size of the buffer is not communicated to the device -
|
| * the device is just asked to send any amount of data.
|
| *
|
| * There is no problem if the device sends an amount of data that is less than
|
| - * or equal to the buffer size. libusb reports this condition to you through
|
| + * or equal to the buffer size. libusbx reports this condition to you through
|
| * the \ref libusb_transfer::actual_length "libusb_transfer.actual_length"
|
| * field.
|
| *
|
| * Problems may occur if the device attempts to send more data than can fit in
|
| - * the buffer. libusb reports LIBUSB_TRANSFER_OVERFLOW for this condition but
|
| + * the buffer. libusbx reports LIBUSB_TRANSFER_OVERFLOW for this condition but
|
| * other behaviour is largely undefined: actual_length may or may not be
|
| * accurate, the chunk of data that can fit in the buffer (before overflow)
|
| * may or may not have been transferred.
|
| @@ -210,7 +212,7 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| /**
|
| * @defgroup asyncio Asynchronous device I/O
|
| *
|
| - * This page details libusb's asynchronous (non-blocking) API for USB device
|
| + * This page details libusbx's asynchronous (non-blocking) API for USB device
|
| * I/O. This interface is very powerful but is also quite complex - you will
|
| * need to read this page carefully to understand the necessary considerations
|
| * and issues surrounding use of this interface. Simplistic applications
|
| @@ -225,7 +227,7 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| *
|
| * \section asyncabstraction Transfer abstraction
|
| *
|
| - * For the asynchronous I/O, libusb implements the concept of a generic
|
| + * For the asynchronous I/O, libusbx implements the concept of a generic
|
| * transfer entity for all types of I/O (control, bulk, interrupt,
|
| * isochronous). The generic transfer object must be treated slightly
|
| * differently depending on which type of I/O you are performing with it.
|
| @@ -238,7 +240,7 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| * -# <b>Allocation</b>: allocate a libusb_transfer
|
| * -# <b>Filling</b>: populate the libusb_transfer instance with information
|
| * about the transfer you wish to perform
|
| - * -# <b>Submission</b>: ask libusb to submit the transfer
|
| + * -# <b>Submission</b>: ask libusbx to submit the transfer
|
| * -# <b>Completion handling</b>: examine transfer results in the
|
| * libusb_transfer structure
|
| * -# <b>Deallocation</b>: clean up resources
|
| @@ -285,7 +287,7 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| *
|
| * The user-specified callback is passed a pointer to the libusb_transfer
|
| * structure which was used to setup and submit the transfer. At completion
|
| - * time, libusb has populated this structure with results of the transfer:
|
| + * time, libusbx has populated this structure with results of the transfer:
|
| * success or failure reason, number of bytes of data transferred, etc. See
|
| * the libusb_transfer structure documentation for more information.
|
| *
|
| @@ -324,7 +326,7 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| * has completed will result in undefined behaviour.
|
| *
|
| * When a transfer is cancelled, some of the data may have been transferred.
|
| - * libusb will communicate this to you in the transfer callback. Do not assume
|
| + * libusbx will communicate this to you in the transfer callback. Do not assume
|
| * that no data was transferred.
|
| *
|
| * \section bulk_overflows Overflows on device-to-host bulk/interrupt endpoints
|
| @@ -466,7 +468,7 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| *
|
| * In most circumstances, it is not safe to use stack memory for transfer
|
| * buffers. This is because the function that fired off the asynchronous
|
| - * transfer may return before libusb has finished using the buffer, and when
|
| + * transfer may return before libusbx has finished using the buffer, and when
|
| * the function returns it's stack gets destroyed. This is true for both
|
| * host-to-device and device-to-host transfers.
|
| *
|
| @@ -486,64 +488,101 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| * \ref libusb_transfer_status::LIBUSB_TRANSFER_ERROR "LIBUSB_TRANSFER_ERROR"
|
| * (they would normally be regarded as COMPLETED)
|
| * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_BUFFER
|
| - * "LIBUSB_TRANSFER_FREE_BUFFER" allows you to ask libusb to free the transfer
|
| + * "LIBUSB_TRANSFER_FREE_BUFFER" allows you to ask libusbx to free the transfer
|
| * buffer when freeing the transfer.
|
| * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_TRANSFER
|
| - * "LIBUSB_TRANSFER_FREE_TRANSFER" causes libusb to automatically free the
|
| + * "LIBUSB_TRANSFER_FREE_TRANSFER" causes libusbx to automatically free the
|
| * transfer after the transfer callback returns.
|
| *
|
| * \section asyncevent Event handling
|
| *
|
| - * In accordance of the aim of being a lightweight library, libusb does not
|
| - * create threads internally. This means that libusb code does not execute
|
| - * at any time other than when your application is calling a libusb function.
|
| - * However, an asynchronous model requires that libusb perform work at various
|
| + * An asynchronous model requires that libusbx perform work at various
|
| * points in time - namely processing the results of previously-submitted
|
| * transfers and invoking the user-supplied callback function.
|
| *
|
| * This gives rise to the libusb_handle_events() function which your
|
| - * application must call into when libusb has work do to. This gives libusb
|
| + * application must call into when libusbx has work do to. This gives libusbx
|
| * the opportunity to reap pending transfers, invoke callbacks, etc.
|
| *
|
| - * The first issue to discuss here is how your application can figure out
|
| - * when libusb has work to do. In fact, there are two naive options which
|
| - * do not actually require your application to know this:
|
| - * -# Periodically call libusb_handle_events() in non-blocking mode at fixed
|
| - * short intervals from your main loop
|
| + * There are 2 different approaches to dealing with libusb_handle_events:
|
| + *
|
| * -# Repeatedly call libusb_handle_events() in blocking mode from a dedicated
|
| * thread.
|
| + * -# Integrate libusbx with your application's main event loop. libusbx
|
| + * exposes a set of file descriptors which allow you to do this.
|
| *
|
| - * The first option is plainly not very nice, and will cause unnecessary
|
| - * CPU wakeups leading to increased power usage and decreased battery life.
|
| - * The second 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 (read on...).
|
| + * The first approach has the big advantage that it will also work on Windows
|
| + * were libusbx' poll API for select / poll integration is not available. So
|
| + * if you want to support Windows and use the async API, you must use this
|
| + * approach, see the \ref eventthread "Using an event handling thread" section
|
| + * below for details.
|
| *
|
| - * The recommended option is to integrate libusb with your application main
|
| - * event loop. libusb exposes a set of file descriptors which allow you to do
|
| - * this. Your main loop is probably already calling poll() or select() or a
|
| - * variant on a set of file descriptors for other event sources (e.g. keyboard
|
| - * button presses, mouse movements, network sockets, etc). You then add
|
| - * libusb's file descriptors to your poll()/select() calls, and when activity
|
| - * is detected on such descriptors you know it is time to call
|
| - * libusb_handle_events().
|
| + * If you prefer a single threaded approach with a single central event loop,
|
| + * see the \ref poll "polling and timing" section for how to integrate libusbx
|
| + * into your application's main event loop.
|
| *
|
| - * There is one final event handling complication. libusb supports
|
| - * asynchronous transfers which time out after a specified time period, and
|
| - * this requires that libusb is called into at or after the timeout so that
|
| - * the timeout can be handled. So, in addition to considering libusb's file
|
| - * descriptors in your main event loop, you must also consider that libusb
|
| - * sometimes needs to be called into at fixed points in time even when there
|
| - * is no file descriptor activity.
|
| + * \section eventthread Using an event handling thread
|
| + *
|
| + * Lets begin with stating the obvious: If you're going to use a separate
|
| + * thread for libusbx event handling, your callback functions MUST be
|
| + * threadsafe.
|
| + *
|
| + * Other then that doing event handling from a separate thread, is mostly
|
| + * simple. You can use an event thread function as follows:
|
| +\code
|
| +void *event_thread_func(void *ctx)
|
| +{
|
| + while (event_thread_run)
|
| + libusb_handle_events(ctx);
|
| +
|
| + return NULL;
|
| +}
|
| +\endcode
|
| + *
|
| + * There is one caveat though, stopping this thread requires setting the
|
| + * event_thread_run variable to 0, and after that libusb_handle_events() needs
|
| + * to return control to event_thread_func. But unless some event happens,
|
| + * libusb_handle_events() will not return.
|
| + *
|
| + * There are 2 different ways of dealing with this, depending on if your
|
| + * application uses libusbx' \ref hotplug "hotplug" support or not.
|
| + *
|
| + * Applications which do not use hotplug support, should not start the event
|
| + * thread until after their first call to libusb_open(), and should stop the
|
| + * thread when closing the last open device as follows:
|
| +\code
|
| +void my_close_handle(libusb_device_handle *handle)
|
| +{
|
| + if (open_devs == 1)
|
| + event_thread_run = 0;
|
| +
|
| + libusb_close(handle); // This wakes up libusb_handle_events()
|
| +
|
| + if (open_devs == 1)
|
| + pthread_join(event_thread);
|
| +
|
| + open_devs--;
|
| +}
|
| +\endcode
|
| *
|
| - * For the details on retrieving the set of file descriptors and determining
|
| - * the next timeout, see the \ref poll "polling and timing" API documentation.
|
| + * Applications using hotplug support should start the thread at program init,
|
| + * after having successfully called libusb_hotplug_register_callback(), and
|
| + * should stop the thread at program exit as follows:
|
| +\code
|
| +void my_libusb_exit(void)
|
| +{
|
| + event_thread_run = 0;
|
| + libusb_hotplug_deregister_callback(ctx, hotplug_cb_handle); // This wakes up libusb_handle_events()
|
| + pthread_join(event_thread);
|
| + libusb_exit(ctx);
|
| +}
|
| +\endcode
|
| */
|
|
|
| /**
|
| * @defgroup poll Polling and timing
|
| *
|
| - * This page documents libusb's functions for polling events and timing.
|
| + * This page documents libusbx's functions for polling events and timing.
|
| * These functions are only necessary for users of the
|
| * \ref asyncio "asynchronous API". If you are only using the simpler
|
| * \ref syncio "synchronous API" then you do not need to ever call these
|
| @@ -551,10 +590,28 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| *
|
| * The justification for the functionality described here has already been
|
| * discussed in the \ref asyncevent "event handling" section of the
|
| - * asynchronous API documentation. In summary, libusb does not create internal
|
| + * asynchronous API documentation. In summary, libusbx does not create internal
|
| * threads for event processing and hence relies on your application calling
|
| - * into libusb at certain points in time so that pending events can be handled.
|
| - * In order to know precisely when libusb needs to be called into, libusb
|
| + * into libusbx at certain points in time so that pending events can be handled.
|
| + *
|
| + * Your main loop is probably already calling poll() or select() or a
|
| + * variant on a set of file descriptors for other event sources (e.g. keyboard
|
| + * button presses, mouse movements, network sockets, etc). You then add
|
| + * libusbx's file descriptors to your poll()/select() calls, and when activity
|
| + * is detected on such descriptors you know it is time to call
|
| + * libusb_handle_events().
|
| + *
|
| + * There is one final event handling complication. libusbx supports
|
| + * asynchronous transfers which time out after a specified time period.
|
| + *
|
| + * On some platforms a timerfd is used, so the timeout handling is just another
|
| + * fd, on other platforms this requires that libusbx is called into at or after
|
| + * the timeout to handle it. So, in addition to considering libusbx's file
|
| + * descriptors in your main event loop, you must also consider that libusbx
|
| + * sometimes needs to be called into at fixed points in time even when there
|
| + * is no file descriptor activity, see \ref polltime details.
|
| + *
|
| + * In order to know precisely when libusbx needs to be called into, libusbx
|
| * offers you a set of pollable file descriptors and information about when
|
| * the next timeout expires.
|
| *
|
| @@ -563,10 +620,10 @@ if (r == 0 && actual_length == sizeof(data)) {
|
| *
|
| * \section pollsimple The simple option
|
| *
|
| - * If your application revolves solely around libusb and does not need to
|
| + * If your application revolves solely around libusbx and does not need to
|
| * handle other event sources, you can have a program structure as follows:
|
| \code
|
| -// initialize libusb
|
| +// initialize libusbx
|
| // find and open device
|
| // maybe fire off some initial async I/O
|
|
|
| @@ -583,20 +640,21 @@ while (user_has_not_requested_exit)
|
| * \section pollmain The more advanced option
|
| *
|
| * \note This functionality is currently only available on Unix-like platforms.
|
| - * On Windows, libusb_get_pollfds() simply returns NULL. Exposing event sources
|
| - * on Windows will require some further thought and design.
|
| + * On Windows, libusb_get_pollfds() simply returns NULL. Applications which
|
| + * want to support Windows are advised to use an \ref eventthread
|
| + * "event handling thread" instead.
|
| *
|
| * In more advanced applications, you will already have a main loop which
|
| * is monitoring other event sources: network sockets, X11 events, mouse
|
| - * movements, etc. Through exposing a set of file descriptors, libusb is
|
| + * movements, etc. Through exposing a set of file descriptors, libusbx is
|
| * designed to cleanly integrate into such main loops.
|
| *
|
| * In addition to polling file descriptors for the other event sources, you
|
| - * take a set of file descriptors from libusb and monitor those too. When you
|
| - * detect activity on libusb's file descriptors, you call
|
| + * take a set of file descriptors from libusbx and monitor those too. When you
|
| + * detect activity on libusbx's file descriptors, you call
|
| * libusb_handle_events_timeout() in non-blocking mode.
|
| *
|
| - * What's more, libusb may also need to handle events at specific moments in
|
| + * What's more, libusbx may also need to handle events at specific moments in
|
| * time. No file descriptor activity is generated at these times, so your
|
| * own application needs to be continually aware of when the next one of these
|
| * moments occurs (through calling libusb_get_next_timeout()), and then it
|
| @@ -604,25 +662,25 @@ while (user_has_not_requested_exit)
|
| * these moments occur. This means that you need to adjust your
|
| * poll()/select() timeout accordingly.
|
| *
|
| - * libusb provides you with a set of file descriptors to poll and expects you
|
| + * libusbx provides you with a set of file descriptors to poll and expects you
|
| * to poll all of them, treating them as a single entity. The meaning of each
|
| * file descriptor in the set is an internal implementation detail,
|
| * platform-dependent and may vary from release to release. Don't try and
|
| - * interpret the meaning of the file descriptors, just do as libusb indicates,
|
| + * interpret the meaning of the file descriptors, just do as libusbx indicates,
|
| * polling all of them at once.
|
| *
|
| * In pseudo-code, you want something that looks like:
|
| \code
|
| -// initialise libusb
|
| +// initialise libusbx
|
|
|
| libusb_get_pollfds(ctx)
|
| while (user has not requested application exit) {
|
| libusb_get_next_timeout(ctx);
|
| - poll(on libusb file descriptors plus any other event sources of interest,
|
| - using a timeout no larger than the value libusb just suggested)
|
| - if (poll() indicated activity on libusb file descriptors)
|
| + poll(on libusbx file descriptors plus any other event sources of interest,
|
| + using a timeout no larger than the value libusbx just suggested)
|
| + if (poll() indicated activity on libusbx file descriptors)
|
| libusb_handle_events_timeout(ctx, &zero_tv);
|
| - if (time has elapsed to or beyond the libusb timeout)
|
| + if (time has elapsed to or beyond the libusbx timeout)
|
| libusb_handle_events_timeout(ctx, &zero_tv);
|
| // handle events from other sources here
|
| }
|
| @@ -632,7 +690,7 @@ while (user has not requested application exit) {
|
| *
|
| * \subsection polltime Notes on time-based events
|
| *
|
| - * The above complication with having to track time and call into libusb at
|
| + * The above complication with having to track time and call into libusbx at
|
| * specific moments is a bit of a headache. For maximum compatibility, you do
|
| * need to write your main loop as above, but you may decide that you can
|
| * restrict the supported platforms of your application and get away with
|
| @@ -644,18 +702,18 @@ while (user has not requested application exit) {
|
| * - Linux, provided that the following version requirements are satisfied:
|
| * - Linux v2.6.27 or newer, compiled with timerfd support
|
| * - glibc v2.9 or newer
|
| - * - libusb v1.0.5 or newer
|
| + * - libusbx v1.0.5 or newer
|
| *
|
| * Under these configurations, libusb_get_next_timeout() will \em always return
|
| * 0, so your main loop can be simplified to:
|
| \code
|
| -// initialise libusb
|
| +// initialise libusbx
|
|
|
| libusb_get_pollfds(ctx)
|
| while (user has not requested application exit) {
|
| - poll(on libusb file descriptors plus any other event sources of interest,
|
| + poll(on libusbx file descriptors plus any other event sources of interest,
|
| using any timeout that you like)
|
| - if (poll() indicated activity on libusb file descriptors)
|
| + if (poll() indicated activity on libusbx file descriptors)
|
| libusb_handle_events_timeout(ctx, &zero_tv);
|
| // handle events from other sources here
|
| }
|
| @@ -665,20 +723,20 @@ while (user has not requested application exit) {
|
| *
|
| * Do remember that if you simplify your main loop to the above, you will
|
| * lose compatibility with some platforms (including legacy Linux platforms,
|
| - * and <em>any future platforms supported by libusb which may have time-based
|
| + * and <em>any future platforms supported by libusbx which may have time-based
|
| * event requirements</em>). The resultant problems will likely appear as
|
| * strange bugs in your application.
|
| *
|
| * You can use the libusb_pollfds_handle_timeouts() function to do a runtime
|
| * check to see if it is safe to ignore the time-based event complications.
|
| - * If your application has taken the shortcut of ignoring libusb's next timeout
|
| + * If your application has taken the shortcut of ignoring libusbx's next timeout
|
| * in your main loop, then you are advised to check the return value of
|
| * libusb_pollfds_handle_timeouts() during application startup, and to abort
|
| * if the platform does suffer from these timing complications.
|
| *
|
| * \subsection fdsetchange Changes in the file descriptor set
|
| *
|
| - * The set of file descriptors that libusb uses as event sources may change
|
| + * The set of file descriptors that libusbx uses as event sources may change
|
| * during the life of your application. Rather than having to repeatedly
|
| * call libusb_get_pollfds(), you can set up notification functions for when
|
| * the file descriptor set changes using libusb_set_pollfd_notifiers().
|
| @@ -699,10 +757,10 @@ while (user has not requested application exit) {
|
|
|
| /** \page mtasync Multi-threaded applications and asynchronous I/O
|
| *
|
| - * libusb is a thread-safe library, but extra considerations must be applied
|
| - * to applications which interact with libusb from multiple threads.
|
| + * libusbx is a thread-safe library, but extra considerations must be applied
|
| + * to applications which interact with libusbx from multiple threads.
|
| *
|
| - * The underlying issue that must be addressed is that all libusb I/O
|
| + * The underlying issue that must be addressed is that all libusbx I/O
|
| * revolves around monitoring file descriptors through the poll()/select()
|
| * system calls. This is directly exposed at the
|
| * \ref asyncio "asynchronous interface" but it is important to note that the
|
| @@ -710,13 +768,13 @@ while (user has not requested application exit) {
|
| * asynchonrous interface, therefore the same considerations apply.
|
| *
|
| * The issue is that if two or more threads are concurrently calling poll()
|
| - * or select() on libusb's file descriptors then only one of those threads
|
| + * or select() on libusbx's file descriptors then only one of those threads
|
| * will be woken up when an event arrives. The others will be completely
|
| * oblivious that anything has happened.
|
| *
|
| * Consider the following pseudo-code, which submits an asynchronous transfer
|
| * then waits for its completion. This style is one way you could implement a
|
| - * synchronous interface on top of the asynchronous interface (and libusb
|
| + * synchronous interface on top of the asynchronous interface (and libusbx
|
| * does something similar, albeit more advanced due to the complications
|
| * explained on this page).
|
| *
|
| @@ -739,7 +797,7 @@ void myfunc() {
|
| libusb_submit_transfer(transfer);
|
|
|
| while (!completed) {
|
| - poll(libusb file descriptors, 120*1000);
|
| + poll(libusbx file descriptors, 120*1000);
|
| if (poll indicates activity)
|
| libusb_handle_events_timeout(ctx, &zero_tv);
|
| }
|
| @@ -753,7 +811,7 @@ void myfunc() {
|
| * The poll() loop has a long timeout to minimize CPU usage during situations
|
| * when nothing is happening (it could reasonably be unlimited).
|
| *
|
| - * If this is the only thread that is polling libusb's file descriptors, there
|
| + * If this is the only thread that is polling libusbx's file descriptors, there
|
| * is no problem: there is no danger that another thread will swallow up the
|
| * event that we are interested in. On the other hand, if there is another
|
| * thread polling the same descriptors, there is a chance that it will receive
|
| @@ -765,13 +823,13 @@ void myfunc() {
|
| *
|
| * The solution here is to ensure that no two threads are ever polling the
|
| * file descriptors at the same time. A naive implementation of this would
|
| - * impact the capabilities of the library, so libusb offers the scheme
|
| + * impact the capabilities of the library, so libusbx offers the scheme
|
| * documented below to ensure no loss of functionality.
|
| *
|
| * Before we go any further, it is worth mentioning that all libusb-wrapped
|
| * event handling procedures fully adhere to the scheme documented below.
|
| * This includes libusb_handle_events() and its variants, and all the
|
| - * synchronous I/O functions - libusb hides this headache from you.
|
| + * synchronous I/O functions - libusbx hides this headache from you.
|
| *
|
| * \section Using libusb_handle_events() from multiple threads
|
| *
|
| @@ -817,17 +875,17 @@ void myfunc() {
|
| *
|
| * \section eventlock The events lock
|
| *
|
| - * The problem is when we consider the fact that libusb exposes file
|
| + * The problem is when we consider the fact that libusbx exposes file
|
| * descriptors to allow for you to integrate asynchronous USB I/O into
|
| * existing main loops, effectively allowing you to do some work behind
|
| - * libusb's back. If you do take libusb's file descriptors and pass them to
|
| + * libusbx's back. If you do take libusbx's file descriptors and pass them to
|
| * poll()/select() yourself, you need to be aware of the associated issues.
|
| *
|
| * The first concept to be introduced is the events lock. The events lock
|
| * is used to serialize threads that want to handle events, such that only
|
| * one thread is handling events at any one time.
|
| *
|
| - * You must take the events lock before polling libusb file descriptors,
|
| + * You must take the events lock before polling libusbx file descriptors,
|
| * using libusb_lock_events(). You must release the lock as soon as you have
|
| * aborted your poll()/select() loop, using libusb_unlock_events().
|
| *
|
| @@ -838,7 +896,7 @@ void myfunc() {
|
| \code
|
| libusb_lock_events(ctx);
|
| while (!completed) {
|
| - poll(libusb file descriptors, 120*1000);
|
| + poll(libusbx file descriptors, 120*1000);
|
| if (poll indicates activity)
|
| libusb_handle_events_timeout(ctx, &zero_tv);
|
| }
|
| @@ -854,7 +912,7 @@ void myfunc() {
|
| * status of its transfer until the code above has finished (30 seconds later)
|
| * due to contention on the lock.
|
| *
|
| - * To solve this, libusb offers you a mechanism to determine when another
|
| + * To solve this, libusbx offers you a mechanism to determine when another
|
| * thread is handling events. It also offers a mechanism to block your thread
|
| * until the event handling thread has completed an event (and this mechanism
|
| * does not involve polling of file descriptors).
|
| @@ -880,7 +938,7 @@ if (libusb_try_lock_events(ctx) == 0) {
|
| libusb_unlock_events(ctx);
|
| goto retry;
|
| }
|
| - poll(libusb file descriptors, 120*1000);
|
| + poll(libusbx file descriptors, 120*1000);
|
| if (poll indicates activity)
|
| libusb_handle_events_locked(ctx, 0);
|
| }
|
| @@ -926,8 +984,8 @@ printf("completed!\n");
|
| * should be apparent from the code shown above.
|
| * -# libusb_try_lock_events() is a non-blocking function which attempts
|
| * to acquire the events lock but returns a failure code if it is contended.
|
| - * -# libusb_event_handling_ok() checks that libusb is still happy for your
|
| - * thread to be performing event handling. Sometimes, libusb needs to
|
| + * -# libusb_event_handling_ok() checks that libusbx is still happy for your
|
| + * thread to be performing event handling. Sometimes, libusbx needs to
|
| * interrupt the event handler, and this is how you can check if you have
|
| * been interrupted. If this function returns 0, the correct behaviour is
|
| * for you to give up the event handling lock, and then to repeat the cycle.
|
| @@ -937,12 +995,12 @@ printf("completed!\n");
|
| * libusb_handle_events_timeout() that you can call while holding the
|
| * events lock. libusb_handle_events_timeout() itself implements similar
|
| * logic to the above, so be sure not to call it when you are
|
| - * "working behind libusb's back", as is the case here.
|
| + * "working behind libusbx's back", as is the case here.
|
| * -# libusb_event_handler_active() determines if someone is currently
|
| * holding the events lock
|
| *
|
| * You might be wondering why there is no function to wake up all threads
|
| - * blocked on libusb_wait_for_event(). This is because libusb can do this
|
| + * blocked on libusb_wait_for_event(). This is because libusbx can do this
|
| * internally: it will wake up all such threads when someone calls
|
| * libusb_unlock_events() or when a transfer completes (at the point after its
|
| * callback has returned).
|
| @@ -951,7 +1009,7 @@ printf("completed!\n");
|
| *
|
| * The above explanation should be enough to get you going, but if you're
|
| * really thinking through the issues then you may be left with some more
|
| - * questions regarding libusb's internals. If you're curious, read on, and if
|
| + * questions regarding libusbx's internals. If you're curious, read on, and if
|
| * not, skip to the next section to avoid confusing yourself!
|
| *
|
| * The immediate question that may spring to mind is: what if one thread
|
| @@ -966,14 +1024,14 @@ printf("completed!\n");
|
| * are all kinds of race conditions that could arise here, so it is
|
| * important that nobody is doing event handling at this time.
|
| *
|
| - * libusb handles these issues internally, so application developers do not
|
| + * libusbx handles these issues internally, so application developers do not
|
| * have to stop their event handlers while opening/closing devices. Here's how
|
| * it works, focusing on the libusb_close() situation first:
|
| *
|
| - * -# During initialization, libusb opens an internal pipe, and it adds the read
|
| + * -# During initialization, libusbx opens an internal pipe, and it adds the read
|
| * end of this pipe to the set of file descriptors to be polled.
|
| - * -# During libusb_close(), libusb writes some dummy data on this control pipe.
|
| - * This immediately interrupts the event handler. libusb also records
|
| + * -# During libusb_close(), libusbx writes some dummy data on this control pipe.
|
| + * This immediately interrupts the event handler. libusbx also records
|
| * internally that it is trying to interrupt event handlers for this
|
| * high-priority event.
|
| * -# At this point, some of the functions described above start behaving
|
| @@ -988,7 +1046,7 @@ printf("completed!\n");
|
| * giving up the events lock very quickly, giving the high-priority
|
| * libusb_close() operation a "free ride" to acquire the events lock. All
|
| * threads that are competing to do event handling become event waiters.
|
| - * -# With the events lock held inside libusb_close(), libusb can safely remove
|
| + * -# With the events lock held inside libusb_close(), libusbx can safely remove
|
| * a file descriptor from the poll set, in the safety of knowledge that
|
| * nobody is polling those descriptors or trying to access the poll set.
|
| * -# After obtaining the events lock, the close operation completes very
|
| @@ -1005,7 +1063,7 @@ printf("completed!\n");
|
| * call to libusb_open():
|
| *
|
| * -# The device is opened and a file descriptor is added to the poll set.
|
| - * -# libusb sends some dummy data on the control pipe, and records that it
|
| + * -# libusbx sends some dummy data on the control pipe, and records that it
|
| * is trying to modify the poll descriptor set.
|
| * -# The event handler is interrupted, and the same behaviour change as for
|
| * libusb_close() takes effect, causing all event handling threads to become
|
| @@ -1021,7 +1079,7 @@ printf("completed!\n");
|
| *
|
| * The above may seem a little complicated, but hopefully I have made it clear
|
| * why such complications are necessary. Also, do not forget that this only
|
| - * applies to applications that take libusb's file descriptors and integrate
|
| + * applies to applications that take libusbx's file descriptors and integrate
|
| * them into their own polling loops.
|
| *
|
| * You may decide that it is OK for your multi-threaded application to ignore
|
| @@ -1070,6 +1128,17 @@ int usbi_io_init(struct libusb_context *ctx)
|
| if (r < 0)
|
| goto err_close_pipe;
|
|
|
| + /* create hotplug pipe */
|
| + r = usbi_pipe(ctx->hotplug_pipe);
|
| + if (r < 0) {
|
| + r = LIBUSB_ERROR_OTHER;
|
| + goto err;
|
| + }
|
| +
|
| + r = usbi_add_pollfd(ctx, ctx->hotplug_pipe[0], POLLIN);
|
| + if (r < 0)
|
| + goto err_close_hp_pipe;
|
| +
|
| #ifdef USBI_TIMERFD_AVAILABLE
|
| ctx->timerfd = timerfd_create(usbi_backend->get_timerfd_clockid(),
|
| TFD_NONBLOCK);
|
| @@ -1079,7 +1148,7 @@ int usbi_io_init(struct libusb_context *ctx)
|
| if (r < 0) {
|
| usbi_remove_pollfd(ctx, ctx->ctrl_pipe[0]);
|
| close(ctx->timerfd);
|
| - goto err_close_pipe;
|
| + goto err_close_hp_pipe;
|
| }
|
| } else {
|
| usbi_dbg("timerfd not available (code %d error %d)", ctx->timerfd, errno);
|
| @@ -1089,6 +1158,9 @@ int usbi_io_init(struct libusb_context *ctx)
|
|
|
| return 0;
|
|
|
| +err_close_hp_pipe:
|
| + usbi_close(ctx->hotplug_pipe[0]);
|
| + usbi_close(ctx->hotplug_pipe[1]);
|
| err_close_pipe:
|
| usbi_close(ctx->ctrl_pipe[0]);
|
| usbi_close(ctx->ctrl_pipe[1]);
|
| @@ -1107,6 +1179,9 @@ void usbi_io_exit(struct libusb_context *ctx)
|
| usbi_remove_pollfd(ctx, ctx->ctrl_pipe[0]);
|
| usbi_close(ctx->ctrl_pipe[0]);
|
| usbi_close(ctx->ctrl_pipe[1]);
|
| + usbi_remove_pollfd(ctx, ctx->hotplug_pipe[0]);
|
| + usbi_close(ctx->hotplug_pipe[0]);
|
| + usbi_close(ctx->hotplug_pipe[1]);
|
| #ifdef USBI_TIMERFD_AVAILABLE
|
| if (usbi_using_timerfd(ctx)) {
|
| usbi_remove_pollfd(ctx, ctx->timerfd);
|
| @@ -1141,7 +1216,7 @@ static int calculate_timeout(struct usbi_transfer *transfer)
|
| current_time.tv_sec += timeout / 1000;
|
| current_time.tv_nsec += (timeout % 1000) * 1000000;
|
|
|
| - if (current_time.tv_nsec > 1000000000) {
|
| + while (current_time.tv_nsec >= 1000000000) {
|
| current_time.tv_nsec -= 1000000000;
|
| current_time.tv_sec++;
|
| }
|
| @@ -1151,8 +1226,10 @@ static int calculate_timeout(struct usbi_transfer *transfer)
|
| }
|
|
|
| /* add a transfer to the (timeout-sorted) active transfers list.
|
| - * returns 1 if the transfer has a timeout and it is the timeout next to
|
| - * expire */
|
| + * Callers of this function must hold the flying_transfers_lock.
|
| + * This function *always* adds the transfer to the flying_transfers list,
|
| + * it will return non 0 if it fails to update the timer, but even then the
|
| + * transfer is added to the flying_transfers list. */
|
| static int add_to_flying_list(struct usbi_transfer *transfer)
|
| {
|
| struct usbi_transfer *cur;
|
| @@ -1161,19 +1238,16 @@ static int add_to_flying_list(struct usbi_transfer *transfer)
|
| int r = 0;
|
| int first = 1;
|
|
|
| - usbi_mutex_lock(&ctx->flying_transfers_lock);
|
| -
|
| /* if we have no other flying transfers, start the list with this one */
|
| if (list_empty(&ctx->flying_transfers)) {
|
| list_add(&transfer->list, &ctx->flying_transfers);
|
| - if (timerisset(timeout))
|
| - r = 1;
|
| goto out;
|
| }
|
|
|
| /* if we have infinite timeout, append to end of list */
|
| if (!timerisset(timeout)) {
|
| list_add_tail(&transfer->list, &ctx->flying_transfers);
|
| + /* first is irrelevant in this case */
|
| goto out;
|
| }
|
|
|
| @@ -1186,21 +1260,38 @@ static int add_to_flying_list(struct usbi_transfer *transfer)
|
| (cur_tv->tv_sec == timeout->tv_sec &&
|
| cur_tv->tv_usec > timeout->tv_usec)) {
|
| list_add_tail(&transfer->list, &cur->list);
|
| - r = first;
|
| goto out;
|
| }
|
| first = 0;
|
| }
|
| + /* first is 0 at this stage (list not empty) */
|
|
|
| /* otherwise we need to be inserted at the end */
|
| list_add_tail(&transfer->list, &ctx->flying_transfers);
|
| out:
|
| - usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
| +#ifdef USBI_TIMERFD_AVAILABLE
|
| + if (first && usbi_using_timerfd(ctx) && timerisset(timeout)) {
|
| + /* if this transfer has the lowest timeout of all active transfers,
|
| + * rearm the timerfd with this transfer's timeout */
|
| + const struct itimerspec it = { {0, 0},
|
| + { timeout->tv_sec, timeout->tv_usec * 1000 } };
|
| + usbi_dbg("arm timerfd for timeout in %dms (first in line)",
|
| + USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout);
|
| + r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL);
|
| + if (r < 0) {
|
| + usbi_warn(ctx, "failed to arm first timerfd (errno %d)", errno);
|
| + r = LIBUSB_ERROR_OTHER;
|
| + }
|
| + }
|
| +#else
|
| + UNUSED(first);
|
| +#endif
|
| +
|
| return r;
|
| }
|
|
|
| /** \ingroup asyncio
|
| - * Allocate a libusb transfer with a specified number of isochronous packet
|
| + * Allocate a libusbx transfer with a specified number of isochronous packet
|
| * descriptors. The returned transfer is pre-initialized for you. When the new
|
| * transfer is no longer needed, it should be freed with
|
| * libusb_free_transfer().
|
| @@ -1232,11 +1323,10 @@ struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(
|
| + sizeof(struct libusb_transfer)
|
| + (sizeof(struct libusb_iso_packet_descriptor) * iso_packets)
|
| + os_alloc_size;
|
| - struct usbi_transfer *itransfer = malloc(alloc_size);
|
| + struct usbi_transfer *itransfer = calloc(1, alloc_size);
|
| if (!itransfer)
|
| return NULL;
|
|
|
| - memset(itransfer, 0, alloc_size);
|
| itransfer->num_iso_packets = iso_packets;
|
| usbi_mutex_init(&itransfer->lock, NULL);
|
| return USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
| @@ -1273,6 +1363,62 @@ void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer)
|
| free(itransfer);
|
| }
|
|
|
| +#ifdef USBI_TIMERFD_AVAILABLE
|
| +static int disarm_timerfd(struct libusb_context *ctx)
|
| +{
|
| + const struct itimerspec disarm_timer = { { 0, 0 }, { 0, 0 } };
|
| + int r;
|
| +
|
| + usbi_dbg("");
|
| + r = timerfd_settime(ctx->timerfd, 0, &disarm_timer, NULL);
|
| + if (r < 0)
|
| + return LIBUSB_ERROR_OTHER;
|
| + else
|
| + return 0;
|
| +}
|
| +
|
| +/* iterates through the flying transfers, and rearms the timerfd based on the
|
| + * next upcoming timeout.
|
| + * must be called with flying_list locked.
|
| + * returns 0 if there was no timeout to arm, 1 if the next timeout was armed,
|
| + * or a LIBUSB_ERROR code on failure.
|
| + */
|
| +static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
|
| +{
|
| + struct usbi_transfer *transfer;
|
| +
|
| + list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
|
| + struct timeval *cur_tv = &transfer->timeout;
|
| +
|
| + /* if we've reached transfers of infinite timeout, then we have no
|
| + * arming to do */
|
| + if (!timerisset(cur_tv))
|
| + goto disarm;
|
| +
|
| + /* act on first transfer that is not already cancelled */
|
| + if (!(transfer->flags & USBI_TRANSFER_TIMED_OUT)) {
|
| + int r;
|
| + const struct itimerspec it = { {0, 0},
|
| + { cur_tv->tv_sec, cur_tv->tv_usec * 1000 } };
|
| + usbi_dbg("next timeout originally %dms", USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout);
|
| + r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL);
|
| + if (r < 0)
|
| + return LIBUSB_ERROR_OTHER;
|
| + return 1;
|
| + }
|
| + }
|
| +
|
| +disarm:
|
| + return disarm_timerfd(ctx);
|
| +}
|
| +#else
|
| +static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
|
| +{
|
| + (void)ctx;
|
| + return 0;
|
| +}
|
| +#endif
|
| +
|
| /** \ingroup asyncio
|
| * Submit a transfer. This function will fire off the USB transfer and then
|
| * return immediately.
|
| @@ -1291,7 +1437,7 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
|
| struct usbi_transfer *itransfer =
|
| LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
|
| int r;
|
| - int first;
|
| + int updated_fds;
|
|
|
| usbi_mutex_lock(&itransfer->lock);
|
| itransfer->transferred = 0;
|
| @@ -1302,30 +1448,22 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
|
| goto out;
|
| }
|
|
|
| - first = add_to_flying_list(itransfer);
|
| - r = usbi_backend->submit_transfer(itransfer);
|
| - if (r) {
|
| - usbi_mutex_lock(&ctx->flying_transfers_lock);
|
| - list_del(&itransfer->list);
|
| - usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
| + usbi_mutex_lock(&ctx->flying_transfers_lock);
|
| + r = add_to_flying_list(itransfer);
|
| + if (r == LIBUSB_SUCCESS) {
|
| + r = usbi_backend->submit_transfer(itransfer);
|
| }
|
| -#ifdef USBI_TIMERFD_AVAILABLE
|
| - else if (first && usbi_using_timerfd(ctx)) {
|
| - /* if this transfer has the lowest timeout of all active transfers,
|
| - * rearm the timerfd with this transfer's timeout */
|
| - const struct itimerspec it = { {0, 0},
|
| - { itransfer->timeout.tv_sec, itransfer->timeout.tv_usec * 1000 } };
|
| - usbi_dbg("arm timerfd for timeout in %dms (first in line)", transfer->timeout);
|
| - r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL);
|
| - if (r < 0)
|
| - r = LIBUSB_ERROR_OTHER;
|
| + if (r != LIBUSB_SUCCESS) {
|
| + list_del(&itransfer->list);
|
| + arm_timerfd_for_next_timeout(ctx);
|
| }
|
| -#else
|
| - (void)first;
|
| -#endif
|
| + usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
|
|
| out:
|
| + updated_fds = (itransfer->flags & USBI_TRANSFER_UPDATED_FDS);
|
| usbi_mutex_unlock(&itransfer->lock);
|
| + if (updated_fds)
|
| + usbi_fd_notification(ctx);
|
| return r;
|
| }
|
|
|
| @@ -1353,7 +1491,8 @@ int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer)
|
| usbi_mutex_lock(&itransfer->lock);
|
| r = usbi_backend->cancel_transfer(itransfer);
|
| if (r < 0) {
|
| - if (r != LIBUSB_ERROR_NOT_FOUND)
|
| + if (r != LIBUSB_ERROR_NOT_FOUND &&
|
| + r != LIBUSB_ERROR_NO_DEVICE)
|
| usbi_err(TRANSFER_CTX(transfer),
|
| "cancel transfer failed error %d", r);
|
| else
|
| @@ -1369,66 +1508,6 @@ int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer)
|
| return r;
|
| }
|
|
|
| -#ifdef USBI_TIMERFD_AVAILABLE
|
| -static int disarm_timerfd(struct libusb_context *ctx)
|
| -{
|
| - const struct itimerspec disarm_timer = { { 0, 0 }, { 0, 0 } };
|
| - int r;
|
| -
|
| - usbi_dbg("");
|
| - r = timerfd_settime(ctx->timerfd, 0, &disarm_timer, NULL);
|
| - if (r < 0)
|
| - return LIBUSB_ERROR_OTHER;
|
| - else
|
| - return 0;
|
| -}
|
| -
|
| -/* iterates through the flying transfers, and rearms the timerfd based on the
|
| - * next upcoming timeout.
|
| - * must be called with flying_list locked.
|
| - * returns 0 if there was no timeout to arm, 1 if the next timeout was armed,
|
| - * or a LIBUSB_ERROR code on failure.
|
| - */
|
| -static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
|
| -{
|
| - struct usbi_transfer *transfer;
|
| -
|
| - list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
|
| - struct timeval *cur_tv = &transfer->timeout;
|
| -
|
| - /* if we've reached transfers of infinite timeout, then we have no
|
| - * arming to do */
|
| - if (!timerisset(cur_tv))
|
| - return 0;
|
| -
|
| - /* act on first transfer that is not already cancelled */
|
| - if (!(transfer->flags & USBI_TRANSFER_TIMED_OUT)) {
|
| - int r;
|
| - const struct itimerspec it = { {0, 0},
|
| - { cur_tv->tv_sec, cur_tv->tv_usec * 1000 } };
|
| - usbi_dbg("next timeout originally %dms", USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout);
|
| - r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL);
|
| - if (r < 0)
|
| - return LIBUSB_ERROR_OTHER;
|
| - return 1;
|
| - }
|
| - }
|
| -
|
| - return 0;
|
| -}
|
| -#else
|
| -static int disarm_timerfd(struct libusb_context *ctx)
|
| -{
|
| - (void)ctx;
|
| - return 0;
|
| -}
|
| -static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
|
| -{
|
| - (void)ctx;
|
| - return 0;
|
| -}
|
| -#endif
|
| -
|
| /* Handle completion of a transfer (completion might be an error condition).
|
| * This will invoke the user-supplied callback function, which may end up
|
| * freeing the transfer. Therefore you cannot use the transfer structure
|
| @@ -1456,14 +1535,8 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
|
| if (usbi_using_timerfd(ctx))
|
| r = arm_timerfd_for_next_timeout(ctx);
|
| usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
| -
|
| - if (usbi_using_timerfd(ctx)) {
|
| - if (r < 0)
|
| - return r;
|
| - r = disarm_timerfd(ctx);
|
| - if (r < 0)
|
| - return r;
|
| - }
|
| + if (usbi_using_timerfd(ctx) && (r < 0))
|
| + return r;
|
|
|
| if (status == LIBUSB_TRANSFER_COMPLETED
|
| && transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) {
|
| @@ -1512,11 +1585,11 @@ int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer)
|
|
|
| /** \ingroup poll
|
| * Attempt to acquire the event handling lock. This lock is used to ensure that
|
| - * only one thread is monitoring libusb event sources at any one time.
|
| + * only one thread is monitoring libusbx event sources at any one time.
|
| *
|
| * You only need to use this lock if you are developing an application
|
| - * which calls poll() or select() on libusb's file descriptors directly.
|
| - * If you stick to libusb's event handling loop functions (e.g.
|
| + * which calls poll() or select() on libusbx's file descriptors directly.
|
| + * If you stick to libusbx's event handling loop functions (e.g.
|
| * libusb_handle_events()) then you do not need to be concerned with this
|
| * locking.
|
| *
|
| @@ -1532,14 +1605,15 @@ int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer)
|
| int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
|
| {
|
| int r;
|
| + unsigned int ru;
|
| USBI_GET_CONTEXT(ctx);
|
|
|
| /* is someone else waiting to modify poll fds? if so, don't let this thread
|
| * start event handling */
|
| usbi_mutex_lock(&ctx->pollfd_modify_lock);
|
| - r = ctx->pollfd_modify;
|
| + ru = ctx->pollfd_modify;
|
| usbi_mutex_unlock(&ctx->pollfd_modify_lock);
|
| - if (r) {
|
| + if (ru) {
|
| usbi_dbg("someone else is modifying poll fds");
|
| return 1;
|
| }
|
| @@ -1555,11 +1629,11 @@ int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
|
| /** \ingroup poll
|
| * Acquire the event handling lock, blocking until successful acquisition if
|
| * it is contended. This lock is used to ensure that only one thread is
|
| - * monitoring libusb event sources at any one time.
|
| + * monitoring libusbx event sources at any one time.
|
| *
|
| * You only need to use this lock if you are developing an application
|
| - * which calls poll() or select() on libusb's file descriptors directly.
|
| - * If you stick to libusb's event handling loop functions (e.g.
|
| + * which calls poll() or select() on libusbx's file descriptors directly.
|
| + * If you stick to libusbx's event handling loop functions (e.g.
|
| * libusb_handle_events()) then you do not need to be concerned with this
|
| * locking.
|
| *
|
| @@ -1602,7 +1676,7 @@ void API_EXPORTED libusb_unlock_events(libusb_context *ctx)
|
| /** \ingroup poll
|
| * Determine if it is still OK for this thread to be doing event handling.
|
| *
|
| - * Sometimes, libusb needs to temporarily pause all event handlers, and this
|
| + * Sometimes, libusbx needs to temporarily pause all event handlers, and this
|
| * is the function you should use before polling file descriptors to see if
|
| * this is the case.
|
| *
|
| @@ -1622,7 +1696,7 @@ void API_EXPORTED libusb_unlock_events(libusb_context *ctx)
|
| */
|
| int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx)
|
| {
|
| - int r;
|
| + unsigned int r;
|
| USBI_GET_CONTEXT(ctx);
|
|
|
| /* is someone else waiting to modify poll fds? if so, don't let this thread
|
| @@ -1650,7 +1724,7 @@ int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx)
|
| */
|
| int API_EXPORTED libusb_event_handler_active(libusb_context *ctx)
|
| {
|
| - int r;
|
| + unsigned int r;
|
| USBI_GET_CONTEXT(ctx);
|
|
|
| /* is someone else waiting to modify poll fds? if so, don't let this thread
|
| @@ -1676,9 +1750,9 @@ int API_EXPORTED libusb_event_handler_active(libusb_context *ctx)
|
| * events, then call libusb_wait_for_event().
|
| *
|
| * You only need to use this lock if you are developing an application
|
| - * which calls poll() or select() on libusb's file descriptors directly,
|
| + * which calls poll() or select() on libusbx's file descriptors directly,
|
| * <b>and</b> may potentially be handling events from 2 threads simultaenously.
|
| - * If you stick to libusb's event handling loop functions (e.g.
|
| + * If you stick to libusbx's event handling loop functions (e.g.
|
| * libusb_handle_events()) then you do not need to be concerned with this
|
| * locking.
|
| *
|
| @@ -1746,7 +1820,7 @@ int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
|
|
|
| timeout.tv_sec += tv->tv_sec;
|
| timeout.tv_nsec += tv->tv_usec * 1000;
|
| - if (timeout.tv_nsec > 1000000000) {
|
| + while (timeout.tv_nsec >= 1000000000) {
|
| timeout.tv_nsec -= 1000000000;
|
| timeout.tv_sec++;
|
| }
|
| @@ -1826,10 +1900,6 @@ static int handle_timerfd_trigger(struct libusb_context *ctx)
|
| {
|
| int r;
|
|
|
| - r = disarm_timerfd(ctx);
|
| - if (r < 0)
|
| - return r;
|
| -
|
| usbi_mutex_lock(&ctx->flying_transfers_lock);
|
|
|
| /* process the timeout that just happened */
|
| @@ -1853,7 +1923,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
|
| int r;
|
| struct usbi_pollfd *ipollfd;
|
| POLL_NFDS_TYPE nfds = 0;
|
| - struct pollfd *fds;
|
| + struct pollfd *fds = NULL;
|
| int i = -1;
|
| int timeout_ms;
|
|
|
| @@ -1862,7 +1932,8 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
|
| nfds++;
|
|
|
| /* TODO: malloc when number of fd's changes, not on every poll */
|
| - fds = malloc(sizeof(*fds) * nfds);
|
| + if (nfds != 0)
|
| + fds = malloc(sizeof(*fds) * nfds);
|
| if (!fds) {
|
| usbi_mutex_unlock(&ctx->pollfds_lock);
|
| return LIBUSB_ERROR_NO_MEM;
|
| @@ -1878,7 +1949,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
|
| }
|
| usbi_mutex_unlock(&ctx->pollfds_lock);
|
|
|
| - timeout_ms = (tv->tv_sec * 1000) + (tv->tv_usec / 1000);
|
| + timeout_ms = (int)(tv->tv_sec * 1000) + (tv->tv_usec / 1000);
|
|
|
| /* round up to next millisecond */
|
| if (tv->tv_usec % 1000)
|
| @@ -1916,9 +1987,36 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
|
| }
|
| }
|
|
|
| + /* fd[1] is always the hotplug pipe */
|
| + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && fds[1].revents) {
|
| + libusb_hotplug_message message;
|
| + ssize_t ret;
|
| +
|
| + usbi_dbg("caught a fish on the hotplug pipe");
|
| +
|
| + /* read the message from the hotplug thread */
|
| + ret = usbi_read(ctx->hotplug_pipe[0], &message, sizeof (message));
|
| + if (ret < sizeof(message)) {
|
| + usbi_err(ctx, "hotplug pipe read error %d < %d",
|
| + ret, sizeof(message));
|
| + r = LIBUSB_ERROR_OTHER;
|
| + goto handled;
|
| + }
|
| +
|
| + usbi_hotplug_match(ctx, message.device, message.event);
|
| +
|
| + /* the device left. dereference the device */
|
| + if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == message.event)
|
| + libusb_unref_device(message.device);
|
| +
|
| + fds[1].revents = 0;
|
| + if (1 == r--)
|
| + goto handled;
|
| + } /* else there shouldn't be anything on this pipe */
|
| +
|
| #ifdef USBI_TIMERFD_AVAILABLE
|
| - /* on timerfd configurations, fds[1] is the timerfd */
|
| - if (usbi_using_timerfd(ctx) && fds[1].revents) {
|
| + /* on timerfd configurations, fds[2] is the timerfd */
|
| + if (usbi_using_timerfd(ctx) && fds[2].revents) {
|
| /* timerfd indicates that a timeout has expired */
|
| int ret;
|
| usbi_dbg("timerfd triggered");
|
| @@ -1935,7 +2033,7 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
|
| } else {
|
| /* more events pending...
|
| * prevent OS backend from trying to handle events on timerfd */
|
| - fds[1].revents = 0;
|
| + fds[2].revents = 0;
|
| r--;
|
| }
|
| }
|
| @@ -1980,7 +2078,7 @@ static int get_next_timeout(libusb_context *ctx, struct timeval *tv,
|
| /** \ingroup poll
|
| * Handle any pending events.
|
| *
|
| - * libusb determines "pending events" by checking if any timeouts have expired
|
| + * libusbx determines "pending events" by checking if any timeouts have expired
|
| * and by checking the set of file descriptors for activity.
|
| *
|
| * If a zero timeval is passed, this function will handle any already-pending
|
| @@ -2129,9 +2227,9 @@ int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx,
|
| * held, see libusb_lock_events().
|
| *
|
| * This function is designed to be called under the situation where you have
|
| - * taken the event lock and are calling poll()/select() directly on libusb's
|
| + * taken the event lock and are calling poll()/select() directly on libusbx's
|
| * file descriptors (as opposed to using libusb_handle_events() or similar).
|
| - * You detect events on libusb's descriptors, so you then call this function
|
| + * You detect events on libusbx's descriptors, so you then call this function
|
| * with a zero timeout value (while still holding the event lock).
|
| *
|
| * \param ctx the context to operate on, or NULL for the default context
|
| @@ -2158,19 +2256,19 @@ int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx,
|
|
|
| /** \ingroup poll
|
| * Determines whether your application must apply special timing considerations
|
| - * when monitoring libusb's file descriptors.
|
| + * when monitoring libusbx's file descriptors.
|
| *
|
| * This function is only useful for applications which retrieve and poll
|
| - * libusb's file descriptors in their own main loop (\ref pollmain).
|
| + * libusbx's file descriptors in their own main loop (\ref pollmain).
|
| *
|
| - * Ordinarily, libusb's event handler needs to be called into at specific
|
| + * Ordinarily, libusbx's event handler needs to be called into at specific
|
| * moments in time (in addition to times when there is activity on the file
|
| * descriptor set). The usual approach is to use libusb_get_next_timeout()
|
| * to learn about when the next timeout occurs, and to adjust your
|
| * poll()/select() timeout accordingly so that you can make a call into the
|
| * library at that time.
|
| *
|
| - * Some platforms supported by libusb do not come with this baggage - any
|
| + * Some platforms supported by libusbx do not come with this baggage - any
|
| * events relevant to timing will be represented by activity on the file
|
| * descriptor set, and libusb_get_next_timeout() will always return 0.
|
| * This function allows you to detect whether you are running on such a
|
| @@ -2179,10 +2277,10 @@ int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx,
|
| * Since v1.0.5.
|
| *
|
| * \param ctx the context to operate on, or NULL for the default context
|
| - * \returns 0 if you must call into libusb at times determined by
|
| + * \returns 0 if you must call into libusbx at times determined by
|
| * libusb_get_next_timeout(), or 1 if all timeout events are handled internally
|
| * or through regular activity on the file descriptors.
|
| - * \see \ref pollmain "Polling libusb file descriptors for event handling"
|
| + * \see \ref pollmain "Polling libusbx file descriptors for event handling"
|
| */
|
| int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx)
|
| {
|
| @@ -2196,21 +2294,21 @@ int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx)
|
| }
|
|
|
| /** \ingroup poll
|
| - * Determine the next internal timeout that libusb needs to handle. You only
|
| + * Determine the next internal timeout that libusbx needs to handle. You only
|
| * need to use this function if you are calling poll() or select() or similar
|
| - * on libusb's file descriptors yourself - you do not need to use it if you
|
| + * on libusbx's file descriptors yourself - you do not need to use it if you
|
| * are calling libusb_handle_events() or a variant directly.
|
| *
|
| * You should call this function in your main loop in order to determine how
|
| - * long to wait for select() or poll() to return results. libusb needs to be
|
| + * long to wait for select() or poll() to return results. libusbx needs to be
|
| * called into at this timeout, so you should use it as an upper bound on
|
| * your select() or poll() call.
|
| *
|
| * When the timeout has expired, call into libusb_handle_events_timeout()
|
| - * (perhaps in non-blocking mode) so that libusb can handle the timeout.
|
| + * (perhaps in non-blocking mode) so that libusbx can handle the timeout.
|
| *
|
| * This function may return 1 (success) and an all-zero timeval. If this is
|
| - * the case, it indicates that libusb has a timeout that has already expired
|
| + * the case, it indicates that libusbx has a timeout that has already expired
|
| * so you should call libusb_handle_events_timeout() or similar immediately.
|
| * A return code of 0 indicates that there are no pending timeouts.
|
| *
|
| @@ -2219,7 +2317,7 @@ int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx)
|
| *
|
| * \param ctx the context to operate on, or NULL for the default context
|
| * \param tv output location for a relative time against the current
|
| - * clock in which libusb must be called into in order to process timeout events
|
| + * clock in which libusbx must be called into in order to process timeout events
|
| * \returns 0 if there are no pending timeouts, 1 if a timeout was returned,
|
| * or LIBUSB_ERROR_OTHER on failure
|
| */
|
| @@ -2268,7 +2366,7 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
|
| r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts);
|
| if (r < 0) {
|
| usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno);
|
| - return LIBUSB_ERROR_OTHER;
|
| + return 0;
|
| }
|
| TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts);
|
|
|
| @@ -2286,7 +2384,7 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
|
| /** \ingroup poll
|
| * Register notification functions for file descriptor additions/removals.
|
| * These functions will be invoked for every new or removed file descriptor
|
| - * that libusb uses as an event source.
|
| + * that libusbx uses as an event source.
|
| *
|
| * To remove notifiers, pass NULL values for the function pointers.
|
| *
|
| @@ -2364,7 +2462,7 @@ void usbi_remove_pollfd(struct libusb_context *ctx, int fd)
|
|
|
| /** \ingroup poll
|
| * Retrieve a list of file descriptors that should be polled by your main loop
|
| - * as libusb event sources.
|
| + * as libusbx event sources.
|
| *
|
| * The returned list is NULL-terminated and should be freed with free() when
|
| * done. The actual list contents must not be touched.
|
| @@ -2404,14 +2502,15 @@ out:
|
| usbi_mutex_unlock(&ctx->pollfds_lock);
|
| return (const struct libusb_pollfd **) ret;
|
| #else
|
| - usbi_err(ctx, "external polling of libusb's internal descriptors "\
|
| + usbi_err(ctx, "external polling of libusbx's internal descriptors "\
|
| "is not yet supported on Windows platforms");
|
| return NULL;
|
| #endif
|
| }
|
|
|
| -/* Backends call this from handle_events to report disconnection of a device.
|
| - * The transfers get cancelled appropriately.
|
| +/* Backends may call this from handle_events to report disconnection of a
|
| + * device. This function ensures transfers get cancelled appropriately.
|
| + * Callers of this function must hold the events_lock.
|
| */
|
| void usbi_handle_disconnect(struct libusb_device_handle *handle)
|
| {
|
| @@ -2426,12 +2525,22 @@ void usbi_handle_disconnect(struct libusb_device_handle *handle)
|
| *
|
| * this is a bit tricky because:
|
| * 1. we can't do transfer completion while holding flying_transfers_lock
|
| + * because the completion handler may try to re-submit the transfer
|
| * 2. the transfers list can change underneath us - if we were to build a
|
| - * list of transfers to complete (while holding look), the situation
|
| + * list of transfers to complete (while holding lock), the situation
|
| * might be different by the time we come to free them
|
| *
|
| * so we resort to a loop-based approach as below
|
| - * FIXME: is this still potentially racy?
|
| + *
|
| + * This is safe because transfers are only removed from the
|
| + * flying_transfer list by usbi_handle_transfer_completion and
|
| + * libusb_close, both of which hold the events_lock while doing so,
|
| + * so usbi_handle_disconnect cannot be running at the same time.
|
| + *
|
| + * Note that libusb_submit_transfer also removes the transfer from
|
| + * the flying_transfer list on submission failure, but it keeps the
|
| + * flying_transfer list locked between addition and removal, so
|
| + * usbi_handle_disconnect never sees such transfers.
|
| */
|
|
|
| while (1) {
|
| @@ -2447,6 +2556,9 @@ void usbi_handle_disconnect(struct libusb_device_handle *handle)
|
| if (!to_cancel)
|
| break;
|
|
|
| + usbi_dbg("cancelling transfer %p from disconnect",
|
| + USBI_TRANSFER_TO_LIBUSB_TRANSFER(to_cancel));
|
| +
|
| usbi_backend->clear_transfer_priv(to_cancel);
|
| usbi_handle_transfer_completion(to_cancel, LIBUSB_TRANSFER_NO_DEVICE);
|
| }
|
|
|