usb 1.7.2 → 1.8.1-libusb.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitmodules +1 -1
- package/Readme.md +2 -2
- package/binding.gyp +2 -2
- package/libusb/.private/pre-commit.sh +7 -1
- package/libusb/.travis.yml +49 -0
- package/libusb/AUTHORS +44 -3
- package/libusb/Brewfile +4 -0
- package/libusb/ChangeLog +74 -2
- package/libusb/README.md +32 -0
- package/libusb/TODO +1 -1
- package/libusb/Xcode/common.xcconfig +12 -0
- package/libusb/Xcode/config.h +25 -0
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +959 -1
- package/libusb/android/README +4 -2
- package/libusb/android/config.h +75 -0
- package/libusb/appveyor.yml +41 -0
- package/libusb/appveyor_cygwin.bat +11 -0
- package/libusb/appveyor_minGW.bat +19 -0
- package/libusb/autogen.sh +1 -1
- package/libusb/bootstrap.sh +3 -16
- package/libusb/configure.ac +108 -80
- package/libusb/doc/doxygen.cfg.in +1785 -739
- package/libusb/examples/Makefile.am +1 -1
- package/libusb/examples/dpfp.c +3 -1
- package/libusb/examples/dpfp_threaded.c +23 -10
- package/libusb/examples/ezusb.c +3 -3
- package/libusb/examples/ezusb.h +2 -2
- package/libusb/examples/fxload.c +31 -9
- package/libusb/examples/hotplugtest.c +35 -7
- package/libusb/examples/listdevs.c +3 -1
- package/libusb/examples/sam3u_benchmark.c +3 -3
- package/libusb/examples/testlibusb.c +277 -0
- package/libusb/examples/xusb.c +40 -34
- package/libusb/libusb/Makefile.am +49 -23
- package/libusb/libusb/core.c +855 -457
- package/libusb/libusb/descriptor.c +72 -78
- package/libusb/libusb/hotplug.c +122 -76
- package/libusb/libusb/hotplug.h +42 -25
- package/libusb/libusb/io.c +625 -390
- package/libusb/libusb/libusb-1.0.def +12 -0
- package/libusb/libusb/libusb.h +218 -150
- package/libusb/libusb/libusbi.h +346 -176
- package/libusb/libusb/os/darwin_usb.c +604 -319
- package/libusb/libusb/os/darwin_usb.h +61 -20
- package/libusb/libusb/os/haiku_pollfs.cpp +367 -0
- package/libusb/libusb/os/haiku_usb.h +113 -0
- package/libusb/libusb/os/haiku_usb_backend.cpp +533 -0
- package/libusb/libusb/os/haiku_usb_raw.cpp +267 -0
- package/libusb/libusb/os/haiku_usb_raw.h +188 -0
- package/libusb/libusb/os/linux_netlink.c +186 -146
- package/libusb/libusb/os/linux_udev.c +36 -14
- package/libusb/libusb/os/linux_usbfs.c +426 -225
- package/libusb/libusb/os/linux_usbfs.h +5 -3
- package/libusb/libusb/os/netbsd_usb.c +21 -77
- package/libusb/libusb/os/openbsd_usb.c +32 -115
- package/libusb/libusb/os/poll_posix.c +38 -5
- package/libusb/libusb/os/poll_posix.h +3 -0
- package/libusb/libusb/os/poll_windows.c +277 -626
- package/libusb/libusb/os/poll_windows.h +11 -44
- package/libusb/libusb/os/sunos_usb.c +1695 -0
- package/libusb/libusb/os/sunos_usb.h +80 -0
- package/libusb/libusb/os/threads_posix.c +24 -26
- package/libusb/libusb/os/threads_posix.h +73 -21
- package/libusb/libusb/os/threads_windows.c +71 -157
- package/libusb/libusb/os/threads_windows.h +68 -44
- package/libusb/libusb/os/wince_usb.c +276 -420
- package/libusb/libusb/os/wince_usb.h +23 -28
- package/libusb/libusb/os/windows_common.h +78 -58
- package/libusb/libusb/os/windows_nt_common.c +1010 -0
- package/libusb/libusb/os/windows_nt_common.h +110 -0
- package/libusb/libusb/os/windows_nt_shared_types.h +147 -0
- package/libusb/libusb/os/windows_usbdk.c +830 -0
- package/libusb/libusb/os/windows_usbdk.h +103 -0
- package/libusb/libusb/os/windows_winusb.c +4391 -0
- package/libusb/libusb/os/windows_winusb.h +783 -0
- package/libusb/libusb/strerror.c +41 -7
- package/libusb/libusb/sync.c +41 -13
- package/libusb/libusb/version.h +1 -1
- package/libusb/libusb/version_nano.h +1 -1
- package/libusb/libusb-1.0.pc.in +1 -1
- package/libusb/msvc/appveyor.bat +27 -0
- package/libusb/msvc/config.h +5 -4
- package/libusb/msvc/ddk_build.cmd +87 -43
- package/libusb/msvc/fxload_2010.vcxproj +24 -104
- package/libusb/msvc/fxload_2012.vcxproj +24 -107
- package/libusb/msvc/fxload_2013.vcxproj +24 -107
- package/libusb/msvc/fxload_2015.vcxproj +91 -0
- package/libusb/msvc/fxload_2017.vcxproj +114 -0
- package/libusb/msvc/fxload_sources +1 -1
- package/libusb/msvc/getopt_2010.vcxproj +16 -75
- package/libusb/msvc/getopt_2012.vcxproj +16 -79
- package/libusb/msvc/getopt_2013.vcxproj +16 -79
- package/libusb/msvc/getopt_2015.vcxproj +73 -0
- package/libusb/msvc/getopt_2017.vcxproj +98 -0
- package/libusb/msvc/getopt_sources +6 -2
- package/libusb/msvc/hotplugtest_2010.vcxproj +18 -99
- package/libusb/msvc/hotplugtest_2012.vcxproj +18 -102
- package/libusb/msvc/hotplugtest_2013.vcxproj +18 -102
- package/libusb/msvc/hotplugtest_2015.vcxproj +83 -0
- package/libusb/msvc/hotplugtest_2017.vcxproj +106 -0
- package/libusb/msvc/hotplugtest_sources +1 -1
- package/libusb/msvc/libusb_2005.sln +20 -20
- package/libusb/msvc/libusb_2010.sln +57 -46
- package/libusb/msvc/libusb_2012.sln +57 -46
- package/libusb/msvc/libusb_2013.sln +57 -50
- package/libusb/msvc/libusb_2015.sln +59 -52
- package/libusb/msvc/libusb_2017.sln +186 -0
- package/libusb/msvc/libusb_dll.dsp +2 -2
- package/libusb/msvc/libusb_dll_2005.vcproj +30 -2
- package/libusb/msvc/libusb_dll_2010.vcxproj +26 -90
- package/libusb/msvc/libusb_dll_2012.vcxproj +28 -96
- package/libusb/msvc/libusb_dll_2013.vcxproj +28 -96
- package/libusb/msvc/libusb_dll_2015.vcxproj +107 -0
- package/libusb/msvc/libusb_dll_2017.vcxproj +134 -0
- package/libusb/msvc/libusb_dll_wince.vcproj +9 -1
- package/libusb/msvc/libusb_sources +10 -5
- package/libusb/msvc/libusb_static.dsp +2 -2
- package/libusb/msvc/libusb_static_2005.vcproj +32 -4
- package/libusb/msvc/libusb_static_2010.vcxproj +24 -83
- package/libusb/msvc/libusb_static_2012.vcxproj +25 -87
- package/libusb/msvc/libusb_static_2013.vcxproj +25 -87
- package/libusb/msvc/libusb_static_2015.vcxproj +98 -0
- package/libusb/msvc/libusb_static_2017.vcxproj +117 -0
- package/libusb/msvc/libusb_static_wince.vcproj +20 -26
- package/libusb/msvc/libusb_wince.sln +88 -88
- package/libusb/msvc/listdevs_2010.vcxproj +16 -99
- package/libusb/msvc/listdevs_2012.vcxproj +16 -102
- package/libusb/msvc/listdevs_2013.vcxproj +16 -102
- package/libusb/msvc/listdevs_2015.vcxproj +83 -0
- package/libusb/msvc/listdevs_2017.vcxproj +106 -0
- package/libusb/msvc/listdevs_sources +2 -1
- package/libusb/msvc/stress_2010.vcxproj +20 -101
- package/libusb/msvc/stress_2012.vcxproj +20 -104
- package/libusb/msvc/stress_2013.vcxproj +20 -104
- package/libusb/msvc/stress_2015.vcxproj +87 -0
- package/libusb/msvc/stress_2017.vcxproj +110 -0
- package/libusb/msvc/stress_sources +21 -0
- package/libusb/msvc/testlibusb_2010.vcxproj +82 -0
- package/libusb/msvc/testlibusb_2012.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2013.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2015.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2017.vcxproj +106 -0
- package/libusb/msvc/testlibusb_sources +20 -0
- package/libusb/msvc/xusb_2010.vcxproj +17 -98
- package/libusb/msvc/xusb_2012.vcxproj +17 -101
- package/libusb/msvc/xusb_2013.vcxproj +17 -101
- package/libusb/msvc/xusb_2015.vcxproj +83 -0
- package/libusb/msvc/xusb_2017.vcxproj +106 -0
- package/libusb/msvc/xusb_sources +1 -1
- package/libusb/tests/stress.c +2 -2
- package/libusb/tests/testlib.c +0 -4
- package/libusb/travis-autogen.sh +39 -0
- package/libusb.gypi +13 -2
- package/package.json +20 -11
- package/prebuilds/android-arm/node.napi.armv7.node +0 -0
- package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
- package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/linux-ia32/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/node.napi.musl.node +0 -0
- package/prebuilds/win32-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/device.cc +1 -1
- package/usb.js +51 -5
- package/.github/workflows/prebuild.yml +0 -49
- package/libusb/INSTALL +0 -234
- package/libusb/README +0 -28
- package/libusb/libusb/os/windows_usb.c +0 -5347
- package/libusb/libusb/os/windows_usb.h +0 -971
- package/libusb/msvc/fxload_2010.vcxproj.filters +0 -25
- package/libusb/msvc/fxload_2012.vcxproj.filters +0 -25
- package/libusb/msvc/getopt_2010.vcxproj.filters +0 -26
- package/libusb/msvc/getopt_2012.vcxproj.filters +0 -26
- package/libusb/msvc/hotplugtest_2010.vcxproj.filters +0 -14
- package/libusb/msvc/hotplugtest_2012.vcxproj.filters +0 -14
- package/libusb/msvc/libusb_dll_2010.vcxproj.filters +0 -81
- package/libusb/msvc/libusb_dll_2012.vcxproj.filters +0 -84
- package/libusb/msvc/libusb_static_2010.vcxproj.filters +0 -74
- package/libusb/msvc/libusb_static_2012.vcxproj.filters +0 -74
- package/libusb/msvc/listdevs_2010.vcxproj.filters +0 -14
- package/libusb/msvc/listdevs_2012.vcxproj.filters +0 -14
- package/libusb/msvc/stress_2010.vcxproj.filters +0 -25
- package/libusb/msvc/stress_2012.vcxproj.filters +0 -25
- package/libusb/msvc/xusb_2010.vcxproj.filters +0 -14
- package/libusb/msvc/xusb_2012.vcxproj.filters +0 -14
package/libusb/libusb/io.c
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* I/O functions for libusb
|
|
4
4
|
* Copyright © 2007-2009 Daniel Drake <dsd@gentoo.org>
|
|
5
5
|
* Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
|
|
6
|
+
* Copyright © 2019 Nathan Hjelm <hjelmn@cs.umm.edu>
|
|
7
|
+
* Copyright © 2019 Google LLC. All rights reserved.
|
|
6
8
|
*
|
|
7
9
|
* This library is free software; you can redistribute it and/or
|
|
8
10
|
* modify it under the terms of the GNU Lesser General Public
|
|
@@ -19,20 +21,19 @@
|
|
|
19
21
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
20
22
|
*/
|
|
21
23
|
|
|
22
|
-
#include
|
|
24
|
+
#include <config.h>
|
|
25
|
+
|
|
23
26
|
#include <assert.h>
|
|
24
27
|
#include <errno.h>
|
|
25
28
|
#include <stdint.h>
|
|
26
29
|
#include <stdlib.h>
|
|
27
30
|
#include <string.h>
|
|
28
31
|
#include <time.h>
|
|
29
|
-
#ifdef HAVE_SIGNAL_H
|
|
30
|
-
#include <signal.h>
|
|
31
|
-
#endif
|
|
32
32
|
#ifdef HAVE_SYS_TIME_H
|
|
33
33
|
#include <sys/time.h>
|
|
34
34
|
#endif
|
|
35
35
|
#ifdef USBI_TIMERFD_AVAILABLE
|
|
36
|
+
#include <unistd.h>
|
|
36
37
|
#include <sys/timerfd.h>
|
|
37
38
|
#endif
|
|
38
39
|
|
|
@@ -40,9 +41,9 @@
|
|
|
40
41
|
#include "hotplug.h"
|
|
41
42
|
|
|
42
43
|
/**
|
|
43
|
-
* \page
|
|
44
|
+
* \page libusb_io Synchronous and asynchronous device I/O
|
|
44
45
|
*
|
|
45
|
-
* \section
|
|
46
|
+
* \section io_intro Introduction
|
|
46
47
|
*
|
|
47
48
|
* If you're using libusb in your application, you're probably wanting to
|
|
48
49
|
* perform I/O with devices - you want to perform USB data transfers.
|
|
@@ -54,8 +55,8 @@
|
|
|
54
55
|
*
|
|
55
56
|
* Once you have read through the following discussion, you should consult the
|
|
56
57
|
* detailed API documentation pages for the details:
|
|
57
|
-
* - \ref
|
|
58
|
-
* - \ref
|
|
58
|
+
* - \ref libusb_syncio
|
|
59
|
+
* - \ref libusb_asyncio
|
|
59
60
|
*
|
|
60
61
|
* \section theory Transfers at a logical level
|
|
61
62
|
*
|
|
@@ -96,7 +97,7 @@
|
|
|
96
97
|
\code
|
|
97
98
|
unsigned char data[4];
|
|
98
99
|
int actual_length;
|
|
99
|
-
int r = libusb_bulk_transfer(
|
|
100
|
+
int r = libusb_bulk_transfer(dev_handle, LIBUSB_ENDPOINT_IN, data, sizeof(data), &actual_length, 0);
|
|
100
101
|
if (r == 0 && actual_length == sizeof(data)) {
|
|
101
102
|
// results of the transaction can now be found in the data buffer
|
|
102
103
|
// parse them here and report button press
|
|
@@ -123,7 +124,7 @@ if (r == 0 && actual_length == sizeof(data)) {
|
|
|
123
124
|
* request has been submitted.
|
|
124
125
|
*
|
|
125
126
|
* For details on how to use the synchronous API, see the
|
|
126
|
-
* \ref
|
|
127
|
+
* \ref libusb_syncio "synchronous I/O API documentation" pages.
|
|
127
128
|
*
|
|
128
129
|
* \section async The asynchronous interface
|
|
129
130
|
*
|
|
@@ -164,12 +165,12 @@ if (r == 0 && actual_length == sizeof(data)) {
|
|
|
164
165
|
* calls to the asynchronous interface.
|
|
165
166
|
*
|
|
166
167
|
* For details on how to use the asynchronous API, see the
|
|
167
|
-
* \ref
|
|
168
|
+
* \ref libusb_asyncio "asynchronous I/O API" documentation pages.
|
|
168
169
|
*/
|
|
169
170
|
|
|
170
171
|
|
|
171
172
|
/**
|
|
172
|
-
* \page
|
|
173
|
+
* \page libusb_packetoverflow Packets and overflows
|
|
173
174
|
*
|
|
174
175
|
* \section packets Packet abstraction
|
|
175
176
|
*
|
|
@@ -211,13 +212,13 @@ if (r == 0 && actual_length == sizeof(data)) {
|
|
|
211
212
|
*/
|
|
212
213
|
|
|
213
214
|
/**
|
|
214
|
-
* @defgroup
|
|
215
|
+
* @defgroup libusb_asyncio Asynchronous device I/O
|
|
215
216
|
*
|
|
216
217
|
* This page details libusb's asynchronous (non-blocking) API for USB device
|
|
217
218
|
* I/O. This interface is very powerful but is also quite complex - you will
|
|
218
219
|
* need to read this page carefully to understand the necessary considerations
|
|
219
220
|
* and issues surrounding use of this interface. Simplistic applications
|
|
220
|
-
* may wish to consider the \ref
|
|
221
|
+
* may wish to consider the \ref libusb_syncio "synchronous I/O API" instead.
|
|
221
222
|
*
|
|
222
223
|
* The asynchronous interface is built around the idea of separating transfer
|
|
223
224
|
* submission and handling of transfer completion (the synchronous model
|
|
@@ -292,6 +293,12 @@ if (r == 0 && actual_length == sizeof(data)) {
|
|
|
292
293
|
* success or failure reason, number of bytes of data transferred, etc. See
|
|
293
294
|
* the libusb_transfer structure documentation for more information.
|
|
294
295
|
*
|
|
296
|
+
* <b>Important Note</b>: The user-specified callback is called from an event
|
|
297
|
+
* handling context. It is therefore important that no calls are made into
|
|
298
|
+
* libusb that will attempt to perform any event handling. Examples of such
|
|
299
|
+
* functions are any listed in the \ref libusb_syncio "synchronous API" and any of
|
|
300
|
+
* the blocking functions that retrieve \ref libusb_desc "USB descriptors".
|
|
301
|
+
*
|
|
295
302
|
* \subsection Deallocation
|
|
296
303
|
*
|
|
297
304
|
* When a transfer has completed (i.e. the callback function has been invoked),
|
|
@@ -336,7 +343,7 @@ if (r == 0 && actual_length == sizeof(data)) {
|
|
|
336
343
|
* your application may submit a request for data on an IN endpoint which is
|
|
337
344
|
* smaller than the data that the device wishes to send. In some circumstances
|
|
338
345
|
* this will cause an overflow, which is a nasty condition to deal with. See
|
|
339
|
-
* the \ref
|
|
346
|
+
* the \ref libusb_packetoverflow page for discussion.
|
|
340
347
|
*
|
|
341
348
|
* \section asyncctrl Considerations for control transfers
|
|
342
349
|
*
|
|
@@ -465,6 +472,14 @@ if (r == 0 && actual_length == sizeof(data)) {
|
|
|
465
472
|
* libusb_get_iso_packet_buffer() and libusb_get_iso_packet_buffer_simple()
|
|
466
473
|
* functions may help you here.
|
|
467
474
|
*
|
|
475
|
+
* <b>Note</b>: Some operating systems (e.g. Linux) may impose limits on the
|
|
476
|
+
* length of individual isochronous packets and/or the total length of the
|
|
477
|
+
* isochronous transfer. Such limits can be difficult for libusb to detect,
|
|
478
|
+
* so the library will simply try and submit the transfer as set up by you.
|
|
479
|
+
* If the transfer fails to submit because it is too large,
|
|
480
|
+
* libusb_submit_transfer() will return
|
|
481
|
+
* \ref libusb_error::LIBUSB_ERROR_INVALID_PARAM "LIBUSB_ERROR_INVALID_PARAM".
|
|
482
|
+
*
|
|
468
483
|
* \section asyncmem Memory caveats
|
|
469
484
|
*
|
|
470
485
|
* In most circumstances, it is not safe to use stack memory for transfer
|
|
@@ -519,7 +534,7 @@ if (r == 0 && actual_length == sizeof(data)) {
|
|
|
519
534
|
* below for details.
|
|
520
535
|
*
|
|
521
536
|
* If you prefer a single threaded approach with a single central event loop,
|
|
522
|
-
* see the \ref
|
|
537
|
+
* see the \ref libusb_poll "polling and timing" section for how to integrate libusb
|
|
523
538
|
* into your application's main event loop.
|
|
524
539
|
*
|
|
525
540
|
* \section eventthread Using an event handling thread
|
|
@@ -546,18 +561,18 @@ void *event_thread_func(void *ctx)
|
|
|
546
561
|
* libusb_handle_events() will not return.
|
|
547
562
|
*
|
|
548
563
|
* There are 2 different ways of dealing with this, depending on if your
|
|
549
|
-
* application uses libusb' \ref
|
|
564
|
+
* application uses libusb' \ref libusb_hotplug "hotplug" support or not.
|
|
550
565
|
*
|
|
551
566
|
* Applications which do not use hotplug support, should not start the event
|
|
552
567
|
* thread until after their first call to libusb_open(), and should stop the
|
|
553
568
|
* thread when closing the last open device as follows:
|
|
554
569
|
\code
|
|
555
|
-
void my_close_handle(libusb_device_handle *
|
|
570
|
+
void my_close_handle(libusb_device_handle *dev_handle)
|
|
556
571
|
{
|
|
557
572
|
if (open_devs == 1)
|
|
558
573
|
event_thread_run = 0;
|
|
559
574
|
|
|
560
|
-
libusb_close(
|
|
575
|
+
libusb_close(dev_handle); // This wakes up libusb_handle_events()
|
|
561
576
|
|
|
562
577
|
if (open_devs == 1)
|
|
563
578
|
pthread_join(event_thread);
|
|
@@ -571,7 +586,7 @@ void my_close_handle(libusb_device_handle *handle)
|
|
|
571
586
|
* should stop the thread at program exit as follows:
|
|
572
587
|
\code
|
|
573
588
|
void my_libusb_exit(void)
|
|
574
|
-
{
|
|
589
|
+
{
|
|
575
590
|
event_thread_run = 0;
|
|
576
591
|
libusb_hotplug_deregister_callback(ctx, hotplug_cb_handle); // This wakes up libusb_handle_events()
|
|
577
592
|
pthread_join(event_thread);
|
|
@@ -581,12 +596,12 @@ void my_libusb_exit(void)
|
|
|
581
596
|
*/
|
|
582
597
|
|
|
583
598
|
/**
|
|
584
|
-
* @defgroup
|
|
599
|
+
* @defgroup libusb_poll Polling and timing
|
|
585
600
|
*
|
|
586
601
|
* This page documents libusb's functions for polling events and timing.
|
|
587
602
|
* These functions are only necessary for users of the
|
|
588
|
-
* \ref
|
|
589
|
-
* \ref
|
|
603
|
+
* \ref libusb_asyncio "asynchronous API". If you are only using the simpler
|
|
604
|
+
* \ref libusb_syncio "synchronous API" then you do not need to ever call these
|
|
590
605
|
* functions.
|
|
591
606
|
*
|
|
592
607
|
* The justification for the functionality described here has already been
|
|
@@ -611,7 +626,7 @@ void my_libusb_exit(void)
|
|
|
611
626
|
* descriptors in your main event loop, you must also consider that libusb
|
|
612
627
|
* sometimes needs to be called into at fixed points in time even when there
|
|
613
628
|
* is no file descriptor activity, see \ref polltime details.
|
|
614
|
-
*
|
|
629
|
+
*
|
|
615
630
|
* In order to know precisely when libusb needs to be called into, libusb
|
|
616
631
|
* offers you a set of pollable file descriptors and information about when
|
|
617
632
|
* the next timeout expires.
|
|
@@ -638,7 +653,7 @@ while (user_has_not_requested_exit)
|
|
|
638
653
|
* sets of file descriptors or handling timeouts. libusb_handle_events() will
|
|
639
654
|
* handle those details internally.
|
|
640
655
|
*
|
|
641
|
-
* \section
|
|
656
|
+
* \section libusb_pollmain The more advanced option
|
|
642
657
|
*
|
|
643
658
|
* \note This functionality is currently only available on Unix-like platforms.
|
|
644
659
|
* On Windows, libusb_get_pollfds() simply returns NULL. Applications which
|
|
@@ -753,10 +768,10 @@ while (user has not requested application exit) {
|
|
|
753
768
|
* entities are added to solve these problems. You do not need to be concerned
|
|
754
769
|
* with these entities otherwise.
|
|
755
770
|
*
|
|
756
|
-
* See the extra documentation: \ref
|
|
771
|
+
* See the extra documentation: \ref libusb_mtasync
|
|
757
772
|
*/
|
|
758
773
|
|
|
759
|
-
/** \page
|
|
774
|
+
/** \page libusb_mtasync Multi-threaded applications and asynchronous I/O
|
|
760
775
|
*
|
|
761
776
|
* libusb is a thread-safe library, but extra considerations must be applied
|
|
762
777
|
* to applications which interact with libusb from multiple threads.
|
|
@@ -764,8 +779,8 @@ while (user has not requested application exit) {
|
|
|
764
779
|
* The underlying issue that must be addressed is that all libusb I/O
|
|
765
780
|
* revolves around monitoring file descriptors through the poll()/select()
|
|
766
781
|
* system calls. This is directly exposed at the
|
|
767
|
-
* \ref
|
|
768
|
-
* \ref
|
|
782
|
+
* \ref libusb_asyncio "asynchronous interface" but it is important to note that the
|
|
783
|
+
* \ref libusb_syncio "synchronous interface" is implemented on top of the
|
|
769
784
|
* asynchonrous interface, therefore the same considerations apply.
|
|
770
785
|
*
|
|
771
786
|
* The issue is that if two or more threads are concurrently calling poll()
|
|
@@ -1031,7 +1046,7 @@ printf("completed!\n");
|
|
|
1031
1046
|
*
|
|
1032
1047
|
* -# During initialization, libusb opens an internal pipe, and it adds the read
|
|
1033
1048
|
* end of this pipe to the set of file descriptors to be polled.
|
|
1034
|
-
* -# During libusb_close(), libusb writes some dummy data on this
|
|
1049
|
+
* -# During libusb_close(), libusb writes some dummy data on this event pipe.
|
|
1035
1050
|
* This immediately interrupts the event handler. libusb also records
|
|
1036
1051
|
* internally that it is trying to interrupt event handlers for this
|
|
1037
1052
|
* high-priority event.
|
|
@@ -1064,7 +1079,7 @@ printf("completed!\n");
|
|
|
1064
1079
|
* call to libusb_open():
|
|
1065
1080
|
*
|
|
1066
1081
|
* -# The device is opened and a file descriptor is added to the poll set.
|
|
1067
|
-
* -# libusb sends some dummy data on the
|
|
1082
|
+
* -# libusb sends some dummy data on the event pipe, and records that it
|
|
1068
1083
|
* is trying to modify the poll descriptor set.
|
|
1069
1084
|
* -# The event handler is interrupted, and the same behaviour change as for
|
|
1070
1085
|
* libusb_close() takes effect, causing all event handling threads to become
|
|
@@ -1092,7 +1107,7 @@ printf("completed!\n");
|
|
|
1092
1107
|
* (without implementing the rules and locking semantics documented above)
|
|
1093
1108
|
* and another trying to send a synchronous USB transfer, you will end up with
|
|
1094
1109
|
* two threads monitoring the same descriptors, and the above-described
|
|
1095
|
-
* undesirable behaviour
|
|
1110
|
+
* undesirable behaviour occurring. The solution is for your polling thread to
|
|
1096
1111
|
* play by the rules; the synchronous I/O functions do so, and this will result
|
|
1097
1112
|
* in them getting along in perfect harmony.
|
|
1098
1113
|
*
|
|
@@ -1109,48 +1124,37 @@ int usbi_io_init(struct libusb_context *ctx)
|
|
|
1109
1124
|
{
|
|
1110
1125
|
int r;
|
|
1111
1126
|
|
|
1112
|
-
usbi_mutex_init(&ctx->flying_transfers_lock
|
|
1113
|
-
usbi_mutex_init(&ctx->
|
|
1114
|
-
usbi_mutex_init(&ctx->
|
|
1115
|
-
|
|
1116
|
-
usbi_mutex_init(&ctx->
|
|
1117
|
-
|
|
1127
|
+
usbi_mutex_init(&ctx->flying_transfers_lock);
|
|
1128
|
+
usbi_mutex_init(&ctx->events_lock);
|
|
1129
|
+
usbi_mutex_init(&ctx->event_waiters_lock);
|
|
1130
|
+
usbi_cond_init(&ctx->event_waiters_cond);
|
|
1131
|
+
usbi_mutex_init(&ctx->event_data_lock);
|
|
1132
|
+
usbi_tls_key_create(&ctx->event_handling_key);
|
|
1118
1133
|
list_init(&ctx->flying_transfers);
|
|
1119
1134
|
list_init(&ctx->ipollfds);
|
|
1135
|
+
list_init(&ctx->removed_ipollfds);
|
|
1136
|
+
list_init(&ctx->hotplug_msgs);
|
|
1137
|
+
list_init(&ctx->completed_transfers);
|
|
1120
1138
|
|
|
1121
1139
|
/* FIXME should use an eventfd on kernels that support it */
|
|
1122
|
-
r = usbi_pipe(ctx->
|
|
1140
|
+
r = usbi_pipe(ctx->event_pipe);
|
|
1123
1141
|
if (r < 0) {
|
|
1124
1142
|
r = LIBUSB_ERROR_OTHER;
|
|
1125
1143
|
goto err;
|
|
1126
1144
|
}
|
|
1127
1145
|
|
|
1128
|
-
r = usbi_add_pollfd(ctx, ctx->
|
|
1146
|
+
r = usbi_add_pollfd(ctx, ctx->event_pipe[0], POLLIN);
|
|
1129
1147
|
if (r < 0)
|
|
1130
1148
|
goto err_close_pipe;
|
|
1131
1149
|
|
|
1132
|
-
/* create hotplug pipe */
|
|
1133
|
-
r = usbi_pipe(ctx->hotplug_pipe);
|
|
1134
|
-
if (r < 0) {
|
|
1135
|
-
r = LIBUSB_ERROR_OTHER;
|
|
1136
|
-
goto err;
|
|
1137
|
-
}
|
|
1138
|
-
|
|
1139
|
-
r = usbi_add_pollfd(ctx, ctx->hotplug_pipe[0], POLLIN);
|
|
1140
|
-
if (r < 0)
|
|
1141
|
-
goto err_close_hp_pipe;
|
|
1142
|
-
|
|
1143
1150
|
#ifdef USBI_TIMERFD_AVAILABLE
|
|
1144
|
-
ctx->timerfd = timerfd_create(usbi_backend
|
|
1145
|
-
TFD_NONBLOCK);
|
|
1151
|
+
ctx->timerfd = timerfd_create(usbi_backend.get_timerfd_clockid(),
|
|
1152
|
+
TFD_NONBLOCK | TFD_CLOEXEC);
|
|
1146
1153
|
if (ctx->timerfd >= 0) {
|
|
1147
1154
|
usbi_dbg("using timerfd for timeouts");
|
|
1148
1155
|
r = usbi_add_pollfd(ctx, ctx->timerfd, POLLIN);
|
|
1149
|
-
if (r < 0)
|
|
1150
|
-
|
|
1151
|
-
close(ctx->timerfd);
|
|
1152
|
-
goto err_close_hp_pipe;
|
|
1153
|
-
}
|
|
1156
|
+
if (r < 0)
|
|
1157
|
+
goto err_close_timerfd;
|
|
1154
1158
|
} else {
|
|
1155
1159
|
usbi_dbg("timerfd not available (code %d error %d)", ctx->timerfd, errno);
|
|
1156
1160
|
ctx->timerfd = -1;
|
|
@@ -1159,30 +1163,38 @@ int usbi_io_init(struct libusb_context *ctx)
|
|
|
1159
1163
|
|
|
1160
1164
|
return 0;
|
|
1161
1165
|
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1166
|
+
#ifdef USBI_TIMERFD_AVAILABLE
|
|
1167
|
+
err_close_timerfd:
|
|
1168
|
+
close(ctx->timerfd);
|
|
1169
|
+
usbi_remove_pollfd(ctx, ctx->event_pipe[0]);
|
|
1170
|
+
#endif
|
|
1165
1171
|
err_close_pipe:
|
|
1166
|
-
usbi_close(ctx->
|
|
1167
|
-
usbi_close(ctx->
|
|
1172
|
+
usbi_close(ctx->event_pipe[0]);
|
|
1173
|
+
usbi_close(ctx->event_pipe[1]);
|
|
1168
1174
|
err:
|
|
1169
1175
|
usbi_mutex_destroy(&ctx->flying_transfers_lock);
|
|
1170
|
-
usbi_mutex_destroy(&ctx->pollfds_lock);
|
|
1171
|
-
usbi_mutex_destroy(&ctx->pollfd_modify_lock);
|
|
1172
1176
|
usbi_mutex_destroy(&ctx->events_lock);
|
|
1173
1177
|
usbi_mutex_destroy(&ctx->event_waiters_lock);
|
|
1174
1178
|
usbi_cond_destroy(&ctx->event_waiters_cond);
|
|
1179
|
+
usbi_mutex_destroy(&ctx->event_data_lock);
|
|
1180
|
+
usbi_tls_key_delete(ctx->event_handling_key);
|
|
1175
1181
|
return r;
|
|
1176
1182
|
}
|
|
1177
1183
|
|
|
1184
|
+
static void cleanup_removed_pollfds(struct libusb_context *ctx)
|
|
1185
|
+
{
|
|
1186
|
+
struct usbi_pollfd *ipollfd, *tmp;
|
|
1187
|
+
list_for_each_entry_safe(ipollfd, tmp, &ctx->removed_ipollfds, list, struct usbi_pollfd) {
|
|
1188
|
+
list_del(&ipollfd->list);
|
|
1189
|
+
free(ipollfd);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1178
1193
|
void usbi_io_exit(struct libusb_context *ctx)
|
|
1179
1194
|
{
|
|
1180
|
-
usbi_remove_pollfd(ctx, ctx->
|
|
1181
|
-
usbi_close(ctx->
|
|
1182
|
-
usbi_close(ctx->
|
|
1183
|
-
usbi_remove_pollfd(ctx, ctx->hotplug_pipe[0]);
|
|
1184
|
-
usbi_close(ctx->hotplug_pipe[0]);
|
|
1185
|
-
usbi_close(ctx->hotplug_pipe[1]);
|
|
1195
|
+
usbi_remove_pollfd(ctx, ctx->event_pipe[0]);
|
|
1196
|
+
usbi_close(ctx->event_pipe[0]);
|
|
1197
|
+
usbi_close(ctx->event_pipe[1]);
|
|
1186
1198
|
#ifdef USBI_TIMERFD_AVAILABLE
|
|
1187
1199
|
if (usbi_using_timerfd(ctx)) {
|
|
1188
1200
|
usbi_remove_pollfd(ctx, ctx->timerfd);
|
|
@@ -1190,13 +1202,13 @@ void usbi_io_exit(struct libusb_context *ctx)
|
|
|
1190
1202
|
}
|
|
1191
1203
|
#endif
|
|
1192
1204
|
usbi_mutex_destroy(&ctx->flying_transfers_lock);
|
|
1193
|
-
usbi_mutex_destroy(&ctx->pollfds_lock);
|
|
1194
|
-
usbi_mutex_destroy(&ctx->pollfd_modify_lock);
|
|
1195
1205
|
usbi_mutex_destroy(&ctx->events_lock);
|
|
1196
1206
|
usbi_mutex_destroy(&ctx->event_waiters_lock);
|
|
1197
1207
|
usbi_cond_destroy(&ctx->event_waiters_cond);
|
|
1198
|
-
|
|
1199
|
-
|
|
1208
|
+
usbi_mutex_destroy(&ctx->event_data_lock);
|
|
1209
|
+
usbi_tls_key_delete(ctx->event_handling_key);
|
|
1210
|
+
free(ctx->pollfds);
|
|
1211
|
+
cleanup_removed_pollfds(ctx);
|
|
1200
1212
|
}
|
|
1201
1213
|
|
|
1202
1214
|
static int calculate_timeout(struct usbi_transfer *transfer)
|
|
@@ -1206,10 +1218,12 @@ static int calculate_timeout(struct usbi_transfer *transfer)
|
|
|
1206
1218
|
unsigned int timeout =
|
|
1207
1219
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout;
|
|
1208
1220
|
|
|
1209
|
-
if (!timeout)
|
|
1221
|
+
if (!timeout) {
|
|
1222
|
+
timerclear(&transfer->timeout);
|
|
1210
1223
|
return 0;
|
|
1224
|
+
}
|
|
1211
1225
|
|
|
1212
|
-
r = usbi_backend
|
|
1226
|
+
r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, ¤t_time);
|
|
1213
1227
|
if (r < 0) {
|
|
1214
1228
|
usbi_err(ITRANSFER_CTX(transfer),
|
|
1215
1229
|
"failed to read monotonic clock, errno=%d", errno);
|
|
@@ -1228,72 +1242,7 @@ static int calculate_timeout(struct usbi_transfer *transfer)
|
|
|
1228
1242
|
return 0;
|
|
1229
1243
|
}
|
|
1230
1244
|
|
|
1231
|
-
|
|
1232
|
-
* Callers of this function must hold the flying_transfers_lock.
|
|
1233
|
-
* This function *always* adds the transfer to the flying_transfers list,
|
|
1234
|
-
* it will return non 0 if it fails to update the timer, but even then the
|
|
1235
|
-
* transfer is added to the flying_transfers list. */
|
|
1236
|
-
static int add_to_flying_list(struct usbi_transfer *transfer)
|
|
1237
|
-
{
|
|
1238
|
-
struct usbi_transfer *cur;
|
|
1239
|
-
struct timeval *timeout = &transfer->timeout;
|
|
1240
|
-
struct libusb_context *ctx = ITRANSFER_CTX(transfer);
|
|
1241
|
-
int r = 0;
|
|
1242
|
-
int first = 1;
|
|
1243
|
-
|
|
1244
|
-
/* if we have no other flying transfers, start the list with this one */
|
|
1245
|
-
if (list_empty(&ctx->flying_transfers)) {
|
|
1246
|
-
list_add(&transfer->list, &ctx->flying_transfers);
|
|
1247
|
-
goto out;
|
|
1248
|
-
}
|
|
1249
|
-
|
|
1250
|
-
/* if we have infinite timeout, append to end of list */
|
|
1251
|
-
if (!timerisset(timeout)) {
|
|
1252
|
-
list_add_tail(&transfer->list, &ctx->flying_transfers);
|
|
1253
|
-
/* first is irrelevant in this case */
|
|
1254
|
-
goto out;
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
|
-
/* otherwise, find appropriate place in list */
|
|
1258
|
-
list_for_each_entry(cur, &ctx->flying_transfers, list, struct usbi_transfer) {
|
|
1259
|
-
/* find first timeout that occurs after the transfer in question */
|
|
1260
|
-
struct timeval *cur_tv = &cur->timeout;
|
|
1261
|
-
|
|
1262
|
-
if (!timerisset(cur_tv) || (cur_tv->tv_sec > timeout->tv_sec) ||
|
|
1263
|
-
(cur_tv->tv_sec == timeout->tv_sec &&
|
|
1264
|
-
cur_tv->tv_usec > timeout->tv_usec)) {
|
|
1265
|
-
list_add_tail(&transfer->list, &cur->list);
|
|
1266
|
-
goto out;
|
|
1267
|
-
}
|
|
1268
|
-
first = 0;
|
|
1269
|
-
}
|
|
1270
|
-
/* first is 0 at this stage (list not empty) */
|
|
1271
|
-
|
|
1272
|
-
/* otherwise we need to be inserted at the end */
|
|
1273
|
-
list_add_tail(&transfer->list, &ctx->flying_transfers);
|
|
1274
|
-
out:
|
|
1275
|
-
#ifdef USBI_TIMERFD_AVAILABLE
|
|
1276
|
-
if (first && usbi_using_timerfd(ctx) && timerisset(timeout)) {
|
|
1277
|
-
/* if this transfer has the lowest timeout of all active transfers,
|
|
1278
|
-
* rearm the timerfd with this transfer's timeout */
|
|
1279
|
-
const struct itimerspec it = { {0, 0},
|
|
1280
|
-
{ timeout->tv_sec, timeout->tv_usec * 1000 } };
|
|
1281
|
-
usbi_dbg("arm timerfd for timeout in %dms (first in line)",
|
|
1282
|
-
USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout);
|
|
1283
|
-
r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL);
|
|
1284
|
-
if (r < 0) {
|
|
1285
|
-
usbi_warn(ctx, "failed to arm first timerfd (errno %d)", errno);
|
|
1286
|
-
r = LIBUSB_ERROR_OTHER;
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
#else
|
|
1290
|
-
UNUSED(first);
|
|
1291
|
-
#endif
|
|
1292
|
-
|
|
1293
|
-
return r;
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
/** \ingroup asyncio
|
|
1245
|
+
/** \ingroup libusb_asyncio
|
|
1297
1246
|
* Allocate a libusb transfer with a specified number of isochronous packet
|
|
1298
1247
|
* descriptors. The returned transfer is pre-initialized for you. When the new
|
|
1299
1248
|
* transfer is no longer needed, it should be freed with
|
|
@@ -1313,29 +1262,37 @@ out:
|
|
|
1313
1262
|
* use it on a non-isochronous endpoint. If you do this, ensure that at time
|
|
1314
1263
|
* of submission, num_iso_packets is 0 and that type is set appropriately.
|
|
1315
1264
|
*
|
|
1316
|
-
* \param iso_packets number of isochronous packet descriptors to allocate
|
|
1265
|
+
* \param iso_packets number of isochronous packet descriptors to allocate. Must be non-negative.
|
|
1317
1266
|
* \returns a newly allocated transfer, or NULL on error
|
|
1318
1267
|
*/
|
|
1319
1268
|
DEFAULT_VISIBILITY
|
|
1320
1269
|
struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(
|
|
1321
1270
|
int iso_packets)
|
|
1322
1271
|
{
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
size_t alloc_size
|
|
1272
|
+
struct libusb_transfer *transfer;
|
|
1273
|
+
size_t os_alloc_size;
|
|
1274
|
+
size_t alloc_size;
|
|
1275
|
+
struct usbi_transfer *itransfer;
|
|
1276
|
+
|
|
1277
|
+
assert(iso_packets >= 0);
|
|
1278
|
+
|
|
1279
|
+
os_alloc_size = usbi_backend.transfer_priv_size;
|
|
1280
|
+
alloc_size = sizeof(struct usbi_transfer)
|
|
1326
1281
|
+ sizeof(struct libusb_transfer)
|
|
1327
|
-
+ (sizeof(struct libusb_iso_packet_descriptor) * iso_packets)
|
|
1282
|
+
+ (sizeof(struct libusb_iso_packet_descriptor) * (size_t)iso_packets)
|
|
1328
1283
|
+ os_alloc_size;
|
|
1329
|
-
|
|
1284
|
+
itransfer = calloc(1, alloc_size);
|
|
1330
1285
|
if (!itransfer)
|
|
1331
1286
|
return NULL;
|
|
1332
1287
|
|
|
1333
1288
|
itransfer->num_iso_packets = iso_packets;
|
|
1334
|
-
usbi_mutex_init(&itransfer->lock
|
|
1335
|
-
|
|
1289
|
+
usbi_mutex_init(&itransfer->lock);
|
|
1290
|
+
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
1291
|
+
usbi_dbg("transfer %p", transfer);
|
|
1292
|
+
return transfer;
|
|
1336
1293
|
}
|
|
1337
1294
|
|
|
1338
|
-
/** \ingroup
|
|
1295
|
+
/** \ingroup libusb_asyncio
|
|
1339
1296
|
* Free a transfer structure. This should be called for all transfers
|
|
1340
1297
|
* allocated with libusb_alloc_transfer().
|
|
1341
1298
|
*
|
|
@@ -1358,7 +1315,8 @@ void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer)
|
|
|
1358
1315
|
if (!transfer)
|
|
1359
1316
|
return;
|
|
1360
1317
|
|
|
1361
|
-
|
|
1318
|
+
usbi_dbg("transfer %p", transfer);
|
|
1319
|
+
if (transfer->flags & LIBUSB_TRANSFER_FREE_BUFFER)
|
|
1362
1320
|
free(transfer->buffer);
|
|
1363
1321
|
|
|
1364
1322
|
itransfer = LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
|
|
@@ -1383,8 +1341,7 @@ static int disarm_timerfd(struct libusb_context *ctx)
|
|
|
1383
1341
|
/* iterates through the flying transfers, and rearms the timerfd based on the
|
|
1384
1342
|
* next upcoming timeout.
|
|
1385
1343
|
* must be called with flying_list locked.
|
|
1386
|
-
* returns 0
|
|
1387
|
-
* or a LIBUSB_ERROR code on failure.
|
|
1344
|
+
* returns 0 on success or a LIBUSB_ERROR code on failure.
|
|
1388
1345
|
*/
|
|
1389
1346
|
static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
|
|
1390
1347
|
{
|
|
@@ -1398,8 +1355,8 @@ static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
|
|
|
1398
1355
|
if (!timerisset(cur_tv))
|
|
1399
1356
|
goto disarm;
|
|
1400
1357
|
|
|
1401
|
-
/* act on first transfer that
|
|
1402
|
-
if (!(transfer->
|
|
1358
|
+
/* act on first transfer that has not already been handled */
|
|
1359
|
+
if (!(transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))) {
|
|
1403
1360
|
int r;
|
|
1404
1361
|
const struct itimerspec it = { {0, 0},
|
|
1405
1362
|
{ cur_tv->tv_sec, cur_tv->tv_usec * 1000 } };
|
|
@@ -1407,7 +1364,7 @@ static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
|
|
|
1407
1364
|
r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL);
|
|
1408
1365
|
if (r < 0)
|
|
1409
1366
|
return LIBUSB_ERROR_OTHER;
|
|
1410
|
-
return
|
|
1367
|
+
return 0;
|
|
1411
1368
|
}
|
|
1412
1369
|
}
|
|
1413
1370
|
|
|
@@ -1417,12 +1374,103 @@ disarm:
|
|
|
1417
1374
|
#else
|
|
1418
1375
|
static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
|
|
1419
1376
|
{
|
|
1420
|
-
(
|
|
1377
|
+
UNUSED(ctx);
|
|
1421
1378
|
return 0;
|
|
1422
1379
|
}
|
|
1423
1380
|
#endif
|
|
1424
1381
|
|
|
1425
|
-
|
|
1382
|
+
/* add a transfer to the (timeout-sorted) active transfers list.
|
|
1383
|
+
* This function will return non 0 if fails to update the timer,
|
|
1384
|
+
* in which case the transfer is *not* on the flying_transfers list. */
|
|
1385
|
+
static int add_to_flying_list(struct usbi_transfer *transfer)
|
|
1386
|
+
{
|
|
1387
|
+
struct usbi_transfer *cur;
|
|
1388
|
+
struct timeval *timeout = &transfer->timeout;
|
|
1389
|
+
struct libusb_context *ctx = ITRANSFER_CTX(transfer);
|
|
1390
|
+
int r;
|
|
1391
|
+
int first = 1;
|
|
1392
|
+
|
|
1393
|
+
r = calculate_timeout(transfer);
|
|
1394
|
+
if (r)
|
|
1395
|
+
return r;
|
|
1396
|
+
|
|
1397
|
+
/* if we have no other flying transfers, start the list with this one */
|
|
1398
|
+
if (list_empty(&ctx->flying_transfers)) {
|
|
1399
|
+
list_add(&transfer->list, &ctx->flying_transfers);
|
|
1400
|
+
goto out;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
/* if we have infinite timeout, append to end of list */
|
|
1404
|
+
if (!timerisset(timeout)) {
|
|
1405
|
+
list_add_tail(&transfer->list, &ctx->flying_transfers);
|
|
1406
|
+
/* first is irrelevant in this case */
|
|
1407
|
+
goto out;
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
/* otherwise, find appropriate place in list */
|
|
1411
|
+
list_for_each_entry(cur, &ctx->flying_transfers, list, struct usbi_transfer) {
|
|
1412
|
+
/* find first timeout that occurs after the transfer in question */
|
|
1413
|
+
struct timeval *cur_tv = &cur->timeout;
|
|
1414
|
+
|
|
1415
|
+
if (!timerisset(cur_tv) || (cur_tv->tv_sec > timeout->tv_sec) ||
|
|
1416
|
+
(cur_tv->tv_sec == timeout->tv_sec &&
|
|
1417
|
+
cur_tv->tv_usec > timeout->tv_usec)) {
|
|
1418
|
+
list_add_tail(&transfer->list, &cur->list);
|
|
1419
|
+
goto out;
|
|
1420
|
+
}
|
|
1421
|
+
first = 0;
|
|
1422
|
+
}
|
|
1423
|
+
/* first is 0 at this stage (list not empty) */
|
|
1424
|
+
|
|
1425
|
+
/* otherwise we need to be inserted at the end */
|
|
1426
|
+
list_add_tail(&transfer->list, &ctx->flying_transfers);
|
|
1427
|
+
out:
|
|
1428
|
+
#ifdef USBI_TIMERFD_AVAILABLE
|
|
1429
|
+
if (first && usbi_using_timerfd(ctx) && timerisset(timeout)) {
|
|
1430
|
+
/* if this transfer has the lowest timeout of all active transfers,
|
|
1431
|
+
* rearm the timerfd with this transfer's timeout */
|
|
1432
|
+
const struct itimerspec it = { {0, 0},
|
|
1433
|
+
{ timeout->tv_sec, timeout->tv_usec * 1000 } };
|
|
1434
|
+
usbi_dbg("arm timerfd for timeout in %dms (first in line)",
|
|
1435
|
+
USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout);
|
|
1436
|
+
r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL);
|
|
1437
|
+
if (r < 0) {
|
|
1438
|
+
usbi_warn(ctx, "failed to arm first timerfd (errno %d)", errno);
|
|
1439
|
+
r = LIBUSB_ERROR_OTHER;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
#else
|
|
1443
|
+
UNUSED(first);
|
|
1444
|
+
#endif
|
|
1445
|
+
|
|
1446
|
+
if (r)
|
|
1447
|
+
list_del(&transfer->list);
|
|
1448
|
+
|
|
1449
|
+
return r;
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
/* remove a transfer from the active transfers list.
|
|
1453
|
+
* This function will *always* remove the transfer from the
|
|
1454
|
+
* flying_transfers list. It will return a LIBUSB_ERROR code
|
|
1455
|
+
* if it fails to update the timer for the next timeout. */
|
|
1456
|
+
static int remove_from_flying_list(struct usbi_transfer *transfer)
|
|
1457
|
+
{
|
|
1458
|
+
struct libusb_context *ctx = ITRANSFER_CTX(transfer);
|
|
1459
|
+
int rearm_timerfd;
|
|
1460
|
+
int r = 0;
|
|
1461
|
+
|
|
1462
|
+
usbi_mutex_lock(&ctx->flying_transfers_lock);
|
|
1463
|
+
rearm_timerfd = (timerisset(&transfer->timeout) &&
|
|
1464
|
+
list_first_entry(&ctx->flying_transfers, struct usbi_transfer, list) == transfer);
|
|
1465
|
+
list_del(&transfer->list);
|
|
1466
|
+
if (usbi_using_timerfd(ctx) && rearm_timerfd)
|
|
1467
|
+
r = arm_timerfd_for_next_timeout(ctx);
|
|
1468
|
+
usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
|
1469
|
+
|
|
1470
|
+
return r;
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
/** \ingroup libusb_asyncio
|
|
1426
1474
|
* Submit a transfer. This function will fire off the USB transfer and then
|
|
1427
1475
|
* return immediately.
|
|
1428
1476
|
*
|
|
@@ -1432,47 +1480,88 @@ static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
|
|
|
1432
1480
|
* \returns LIBUSB_ERROR_BUSY if the transfer has already been submitted.
|
|
1433
1481
|
* \returns LIBUSB_ERROR_NOT_SUPPORTED if the transfer flags are not supported
|
|
1434
1482
|
* by the operating system.
|
|
1483
|
+
* \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than
|
|
1484
|
+
* the operating system and/or hardware can support
|
|
1435
1485
|
* \returns another LIBUSB_ERROR code on other failure
|
|
1436
1486
|
*/
|
|
1437
1487
|
int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
|
|
1438
1488
|
{
|
|
1439
|
-
struct libusb_context *ctx = TRANSFER_CTX(transfer);
|
|
1440
1489
|
struct usbi_transfer *itransfer =
|
|
1441
1490
|
LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
|
|
1491
|
+
struct libusb_context *ctx = TRANSFER_CTX(transfer);
|
|
1442
1492
|
int r;
|
|
1443
|
-
int updated_fds;
|
|
1444
1493
|
|
|
1494
|
+
usbi_dbg("transfer %p", transfer);
|
|
1495
|
+
|
|
1496
|
+
/*
|
|
1497
|
+
* Important note on locking, this function takes / releases locks
|
|
1498
|
+
* in the following order:
|
|
1499
|
+
* take flying_transfers_lock
|
|
1500
|
+
* take itransfer->lock
|
|
1501
|
+
* clear transfer
|
|
1502
|
+
* add to flying_transfers list
|
|
1503
|
+
* release flying_transfers_lock
|
|
1504
|
+
* submit transfer
|
|
1505
|
+
* release itransfer->lock
|
|
1506
|
+
* if submit failed:
|
|
1507
|
+
* take flying_transfers_lock
|
|
1508
|
+
* remove from flying_transfers list
|
|
1509
|
+
* release flying_transfers_lock
|
|
1510
|
+
*
|
|
1511
|
+
* Note that it takes locks in the order a-b and then releases them
|
|
1512
|
+
* in the same order a-b. This is somewhat unusual but not wrong,
|
|
1513
|
+
* release order is not important as long as *all* locks are released
|
|
1514
|
+
* before re-acquiring any locks.
|
|
1515
|
+
*
|
|
1516
|
+
* This means that the ordering of first releasing itransfer->lock
|
|
1517
|
+
* and then re-acquiring the flying_transfers_list on error is
|
|
1518
|
+
* important and must not be changed!
|
|
1519
|
+
*
|
|
1520
|
+
* This is done this way because when we take both locks we must always
|
|
1521
|
+
* take flying_transfers_lock first to avoid ab-ba style deadlocks with
|
|
1522
|
+
* the timeout handling and usbi_handle_disconnect paths.
|
|
1523
|
+
*
|
|
1524
|
+
* And we cannot release itransfer->lock before the submission is
|
|
1525
|
+
* complete otherwise timeout handling for transfers with short
|
|
1526
|
+
* timeouts may run before submission.
|
|
1527
|
+
*/
|
|
1445
1528
|
usbi_mutex_lock(&ctx->flying_transfers_lock);
|
|
1446
1529
|
usbi_mutex_lock(&itransfer->lock);
|
|
1530
|
+
if (itransfer->state_flags & USBI_TRANSFER_IN_FLIGHT) {
|
|
1531
|
+
usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
|
1532
|
+
usbi_mutex_unlock(&itransfer->lock);
|
|
1533
|
+
return LIBUSB_ERROR_BUSY;
|
|
1534
|
+
}
|
|
1447
1535
|
itransfer->transferred = 0;
|
|
1448
|
-
itransfer->
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1536
|
+
itransfer->state_flags = 0;
|
|
1537
|
+
itransfer->timeout_flags = 0;
|
|
1538
|
+
r = add_to_flying_list(itransfer);
|
|
1539
|
+
if (r) {
|
|
1540
|
+
usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
|
1541
|
+
usbi_mutex_unlock(&itransfer->lock);
|
|
1542
|
+
return r;
|
|
1453
1543
|
}
|
|
1544
|
+
/*
|
|
1545
|
+
* We must release the flying transfers lock here, because with
|
|
1546
|
+
* some backends the submit_transfer method is synchroneous.
|
|
1547
|
+
*/
|
|
1548
|
+
usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
|
1454
1549
|
|
|
1455
|
-
r =
|
|
1550
|
+
r = usbi_backend.submit_transfer(itransfer);
|
|
1456
1551
|
if (r == LIBUSB_SUCCESS) {
|
|
1457
|
-
|
|
1458
|
-
}
|
|
1459
|
-
if (r != LIBUSB_SUCCESS) {
|
|
1460
|
-
list_del(&itransfer->list);
|
|
1461
|
-
arm_timerfd_for_next_timeout(ctx);
|
|
1462
|
-
} else {
|
|
1552
|
+
itransfer->state_flags |= USBI_TRANSFER_IN_FLIGHT;
|
|
1463
1553
|
/* keep a reference to this device */
|
|
1464
1554
|
libusb_ref_device(transfer->dev_handle->dev);
|
|
1465
1555
|
}
|
|
1466
|
-
out:
|
|
1467
|
-
updated_fds = (itransfer->flags & USBI_TRANSFER_UPDATED_FDS);
|
|
1468
1556
|
usbi_mutex_unlock(&itransfer->lock);
|
|
1469
|
-
|
|
1470
|
-
if (
|
|
1471
|
-
|
|
1557
|
+
|
|
1558
|
+
if (r != LIBUSB_SUCCESS)
|
|
1559
|
+
remove_from_flying_list(itransfer);
|
|
1560
|
+
|
|
1472
1561
|
return r;
|
|
1473
1562
|
}
|
|
1474
1563
|
|
|
1475
|
-
/** \ingroup
|
|
1564
|
+
/** \ingroup libusb_asyncio
|
|
1476
1565
|
* Asynchronously cancel a previously submitted transfer.
|
|
1477
1566
|
* This function returns immediately, but this does not indicate cancellation
|
|
1478
1567
|
* is complete. Your callback function will be invoked at some later time
|
|
@@ -1482,8 +1571,8 @@ out:
|
|
|
1482
1571
|
*
|
|
1483
1572
|
* \param transfer the transfer to cancel
|
|
1484
1573
|
* \returns 0 on success
|
|
1485
|
-
* \returns LIBUSB_ERROR_NOT_FOUND if the transfer is
|
|
1486
|
-
* cancelled.
|
|
1574
|
+
* \returns LIBUSB_ERROR_NOT_FOUND if the transfer is not in progress,
|
|
1575
|
+
* already complete, or already cancelled.
|
|
1487
1576
|
* \returns a LIBUSB_ERROR code on failure
|
|
1488
1577
|
*/
|
|
1489
1578
|
int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer)
|
|
@@ -1492,9 +1581,14 @@ int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer)
|
|
|
1492
1581
|
LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
|
|
1493
1582
|
int r;
|
|
1494
1583
|
|
|
1495
|
-
usbi_dbg("");
|
|
1584
|
+
usbi_dbg("transfer %p", transfer );
|
|
1496
1585
|
usbi_mutex_lock(&itransfer->lock);
|
|
1497
|
-
|
|
1586
|
+
if (!(itransfer->state_flags & USBI_TRANSFER_IN_FLIGHT)
|
|
1587
|
+
|| (itransfer->state_flags & USBI_TRANSFER_CANCELLING)) {
|
|
1588
|
+
r = LIBUSB_ERROR_NOT_FOUND;
|
|
1589
|
+
goto out;
|
|
1590
|
+
}
|
|
1591
|
+
r = usbi_backend.cancel_transfer(itransfer);
|
|
1498
1592
|
if (r < 0) {
|
|
1499
1593
|
if (r != LIBUSB_ERROR_NOT_FOUND &&
|
|
1500
1594
|
r != LIBUSB_ERROR_NO_DEVICE)
|
|
@@ -1504,16 +1598,17 @@ int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer)
|
|
|
1504
1598
|
usbi_dbg("cancel transfer failed error %d", r);
|
|
1505
1599
|
|
|
1506
1600
|
if (r == LIBUSB_ERROR_NO_DEVICE)
|
|
1507
|
-
itransfer->
|
|
1601
|
+
itransfer->state_flags |= USBI_TRANSFER_DEVICE_DISAPPEARED;
|
|
1508
1602
|
}
|
|
1509
1603
|
|
|
1510
|
-
itransfer->
|
|
1604
|
+
itransfer->state_flags |= USBI_TRANSFER_CANCELLING;
|
|
1511
1605
|
|
|
1606
|
+
out:
|
|
1512
1607
|
usbi_mutex_unlock(&itransfer->lock);
|
|
1513
1608
|
return r;
|
|
1514
1609
|
}
|
|
1515
1610
|
|
|
1516
|
-
/** \ingroup
|
|
1611
|
+
/** \ingroup libusb_asyncio
|
|
1517
1612
|
* Set a transfers bulk stream id. Note users are advised to use
|
|
1518
1613
|
* libusb_fill_bulk_stream_transfer() instead of calling this function
|
|
1519
1614
|
* directly.
|
|
@@ -1533,7 +1628,7 @@ void API_EXPORTED libusb_transfer_set_stream_id(
|
|
|
1533
1628
|
itransfer->stream_id = stream_id;
|
|
1534
1629
|
}
|
|
1535
1630
|
|
|
1536
|
-
/** \ingroup
|
|
1631
|
+
/** \ingroup libusb_asyncio
|
|
1537
1632
|
* Get a transfers bulk stream id.
|
|
1538
1633
|
*
|
|
1539
1634
|
* Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103
|
|
@@ -1563,23 +1658,17 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
|
|
|
1563
1658
|
{
|
|
1564
1659
|
struct libusb_transfer *transfer =
|
|
1565
1660
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
1566
|
-
struct
|
|
1567
|
-
struct libusb_device_handle *handle = transfer->dev_handle;
|
|
1661
|
+
struct libusb_device_handle *dev_handle = transfer->dev_handle;
|
|
1568
1662
|
uint8_t flags;
|
|
1569
|
-
int r
|
|
1663
|
+
int r;
|
|
1570
1664
|
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
* the shortest timeout. */
|
|
1665
|
+
r = remove_from_flying_list(itransfer);
|
|
1666
|
+
if (r < 0)
|
|
1667
|
+
usbi_err(ITRANSFER_CTX(itransfer), "failed to set timer for next timeout, errno=%d", errno);
|
|
1575
1668
|
|
|
1576
|
-
usbi_mutex_lock(&
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
r = arm_timerfd_for_next_timeout(ctx);
|
|
1580
|
-
usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
|
1581
|
-
if (usbi_using_timerfd(ctx) && (r < 0))
|
|
1582
|
-
return r;
|
|
1669
|
+
usbi_mutex_lock(&itransfer->lock);
|
|
1670
|
+
itransfer->state_flags &= ~USBI_TRANSFER_IN_FLIGHT;
|
|
1671
|
+
usbi_mutex_unlock(&itransfer->lock);
|
|
1583
1672
|
|
|
1584
1673
|
if (status == LIBUSB_TRANSFER_COMPLETED
|
|
1585
1674
|
&& transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) {
|
|
@@ -1602,8 +1691,8 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
|
|
|
1602
1691
|
* this point. */
|
|
1603
1692
|
if (flags & LIBUSB_TRANSFER_FREE_TRANSFER)
|
|
1604
1693
|
libusb_free_transfer(transfer);
|
|
1605
|
-
libusb_unref_device(
|
|
1606
|
-
return
|
|
1694
|
+
libusb_unref_device(dev_handle->dev);
|
|
1695
|
+
return r;
|
|
1607
1696
|
}
|
|
1608
1697
|
|
|
1609
1698
|
/* Similar to usbi_handle_transfer_completion() but exclusively for transfers
|
|
@@ -1614,8 +1703,15 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
|
|
|
1614
1703
|
* will attempt to take the lock. */
|
|
1615
1704
|
int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer)
|
|
1616
1705
|
{
|
|
1706
|
+
struct libusb_context *ctx = ITRANSFER_CTX(transfer);
|
|
1707
|
+
uint8_t timed_out;
|
|
1708
|
+
|
|
1709
|
+
usbi_mutex_lock(&ctx->flying_transfers_lock);
|
|
1710
|
+
timed_out = transfer->timeout_flags & USBI_TRANSFER_TIMED_OUT;
|
|
1711
|
+
usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
|
1712
|
+
|
|
1617
1713
|
/* if the URB was cancelled due to timeout, report timeout to the user */
|
|
1618
|
-
if (
|
|
1714
|
+
if (timed_out) {
|
|
1619
1715
|
usbi_dbg("detected timeout cancellation");
|
|
1620
1716
|
return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_TIMED_OUT);
|
|
1621
1717
|
}
|
|
@@ -1624,7 +1720,27 @@ int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer)
|
|
|
1624
1720
|
return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_CANCELLED);
|
|
1625
1721
|
}
|
|
1626
1722
|
|
|
1627
|
-
|
|
1723
|
+
/* Add a completed transfer to the completed_transfers list of the
|
|
1724
|
+
* context and signal the event. The backend's handle_transfer_completion()
|
|
1725
|
+
* function will be called the next time an event handler runs. */
|
|
1726
|
+
void usbi_signal_transfer_completion(struct usbi_transfer *transfer)
|
|
1727
|
+
{
|
|
1728
|
+
libusb_device_handle *dev_handle = USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->dev_handle;
|
|
1729
|
+
|
|
1730
|
+
if (dev_handle) {
|
|
1731
|
+
struct libusb_context *ctx = HANDLE_CTX(dev_handle);
|
|
1732
|
+
int pending_events;
|
|
1733
|
+
|
|
1734
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
1735
|
+
pending_events = usbi_pending_events(ctx);
|
|
1736
|
+
list_add_tail(&transfer->completed_list, &ctx->completed_transfers);
|
|
1737
|
+
if (!pending_events)
|
|
1738
|
+
usbi_signal_event(ctx);
|
|
1739
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
/** \ingroup libusb_poll
|
|
1628
1744
|
* Attempt to acquire the event handling lock. This lock is used to ensure that
|
|
1629
1745
|
* only one thread is monitoring libusb event sources at any one time.
|
|
1630
1746
|
*
|
|
@@ -1641,7 +1757,7 @@ int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer)
|
|
|
1641
1757
|
* \param ctx the context to operate on, or NULL for the default context
|
|
1642
1758
|
* \returns 0 if the lock was obtained successfully
|
|
1643
1759
|
* \returns 1 if the lock was not obtained (i.e. another thread holds the lock)
|
|
1644
|
-
* \ref
|
|
1760
|
+
* \ref libusb_mtasync
|
|
1645
1761
|
*/
|
|
1646
1762
|
int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
|
|
1647
1763
|
{
|
|
@@ -1649,13 +1765,13 @@ int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
|
|
|
1649
1765
|
unsigned int ru;
|
|
1650
1766
|
USBI_GET_CONTEXT(ctx);
|
|
1651
1767
|
|
|
1652
|
-
/* is someone else waiting to
|
|
1768
|
+
/* is someone else waiting to close a device? if so, don't let this thread
|
|
1653
1769
|
* start event handling */
|
|
1654
|
-
usbi_mutex_lock(&ctx->
|
|
1655
|
-
ru = ctx->
|
|
1656
|
-
usbi_mutex_unlock(&ctx->
|
|
1770
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
1771
|
+
ru = ctx->device_close;
|
|
1772
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
1657
1773
|
if (ru) {
|
|
1658
|
-
usbi_dbg("someone else is
|
|
1774
|
+
usbi_dbg("someone else is closing a device");
|
|
1659
1775
|
return 1;
|
|
1660
1776
|
}
|
|
1661
1777
|
|
|
@@ -1667,7 +1783,7 @@ int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
|
|
|
1667
1783
|
return 0;
|
|
1668
1784
|
}
|
|
1669
1785
|
|
|
1670
|
-
/** \ingroup
|
|
1786
|
+
/** \ingroup libusb_poll
|
|
1671
1787
|
* Acquire the event handling lock, blocking until successful acquisition if
|
|
1672
1788
|
* it is contended. This lock is used to ensure that only one thread is
|
|
1673
1789
|
* monitoring libusb event sources at any one time.
|
|
@@ -1683,7 +1799,7 @@ int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
|
|
|
1683
1799
|
* as soon as possible.
|
|
1684
1800
|
*
|
|
1685
1801
|
* \param ctx the context to operate on, or NULL for the default context
|
|
1686
|
-
* \ref
|
|
1802
|
+
* \ref libusb_mtasync
|
|
1687
1803
|
*/
|
|
1688
1804
|
void API_EXPORTED libusb_lock_events(libusb_context *ctx)
|
|
1689
1805
|
{
|
|
@@ -1692,13 +1808,13 @@ void API_EXPORTED libusb_lock_events(libusb_context *ctx)
|
|
|
1692
1808
|
ctx->event_handler_active = 1;
|
|
1693
1809
|
}
|
|
1694
1810
|
|
|
1695
|
-
/** \ingroup
|
|
1811
|
+
/** \ingroup libusb_poll
|
|
1696
1812
|
* Release the lock previously acquired with libusb_try_lock_events() or
|
|
1697
1813
|
* libusb_lock_events(). Releasing this lock will wake up any threads blocked
|
|
1698
1814
|
* on libusb_wait_for_event().
|
|
1699
1815
|
*
|
|
1700
1816
|
* \param ctx the context to operate on, or NULL for the default context
|
|
1701
|
-
* \ref
|
|
1817
|
+
* \ref libusb_mtasync
|
|
1702
1818
|
*/
|
|
1703
1819
|
void API_EXPORTED libusb_unlock_events(libusb_context *ctx)
|
|
1704
1820
|
{
|
|
@@ -1708,13 +1824,13 @@ void API_EXPORTED libusb_unlock_events(libusb_context *ctx)
|
|
|
1708
1824
|
|
|
1709
1825
|
/* FIXME: perhaps we should be a bit more efficient by not broadcasting
|
|
1710
1826
|
* the availability of the events lock when we are modifying pollfds
|
|
1711
|
-
* (check ctx->
|
|
1827
|
+
* (check ctx->device_close)? */
|
|
1712
1828
|
usbi_mutex_lock(&ctx->event_waiters_lock);
|
|
1713
1829
|
usbi_cond_broadcast(&ctx->event_waiters_cond);
|
|
1714
1830
|
usbi_mutex_unlock(&ctx->event_waiters_lock);
|
|
1715
1831
|
}
|
|
1716
1832
|
|
|
1717
|
-
/** \ingroup
|
|
1833
|
+
/** \ingroup libusb_poll
|
|
1718
1834
|
* Determine if it is still OK for this thread to be doing event handling.
|
|
1719
1835
|
*
|
|
1720
1836
|
* Sometimes, libusb needs to temporarily pause all event handlers, and this
|
|
@@ -1722,7 +1838,7 @@ void API_EXPORTED libusb_unlock_events(libusb_context *ctx)
|
|
|
1722
1838
|
* this is the case.
|
|
1723
1839
|
*
|
|
1724
1840
|
* If this function instructs your thread to give up the events lock, you
|
|
1725
|
-
* should just continue the usual logic that is documented in \ref
|
|
1841
|
+
* should just continue the usual logic that is documented in \ref libusb_mtasync.
|
|
1726
1842
|
* On the next iteration, your thread will fail to obtain the events lock,
|
|
1727
1843
|
* and will hence become an event waiter.
|
|
1728
1844
|
*
|
|
@@ -1740,13 +1856,13 @@ int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx)
|
|
|
1740
1856
|
unsigned int r;
|
|
1741
1857
|
USBI_GET_CONTEXT(ctx);
|
|
1742
1858
|
|
|
1743
|
-
/* is someone else waiting to
|
|
1859
|
+
/* is someone else waiting to close a device? if so, don't let this thread
|
|
1744
1860
|
* continue event handling */
|
|
1745
|
-
usbi_mutex_lock(&ctx->
|
|
1746
|
-
r = ctx->
|
|
1747
|
-
usbi_mutex_unlock(&ctx->
|
|
1861
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
1862
|
+
r = ctx->device_close;
|
|
1863
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
1748
1864
|
if (r) {
|
|
1749
|
-
usbi_dbg("someone else is
|
|
1865
|
+
usbi_dbg("someone else is closing a device");
|
|
1750
1866
|
return 0;
|
|
1751
1867
|
}
|
|
1752
1868
|
|
|
@@ -1754,34 +1870,60 @@ int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx)
|
|
|
1754
1870
|
}
|
|
1755
1871
|
|
|
1756
1872
|
|
|
1757
|
-
/** \ingroup
|
|
1873
|
+
/** \ingroup libusb_poll
|
|
1758
1874
|
* Determine if an active thread is handling events (i.e. if anyone is holding
|
|
1759
1875
|
* the event handling lock).
|
|
1760
1876
|
*
|
|
1761
1877
|
* \param ctx the context to operate on, or NULL for the default context
|
|
1762
1878
|
* \returns 1 if a thread is handling events
|
|
1763
1879
|
* \returns 0 if there are no threads currently handling events
|
|
1764
|
-
* \ref
|
|
1880
|
+
* \ref libusb_mtasync
|
|
1765
1881
|
*/
|
|
1766
1882
|
int API_EXPORTED libusb_event_handler_active(libusb_context *ctx)
|
|
1767
1883
|
{
|
|
1768
1884
|
unsigned int r;
|
|
1769
1885
|
USBI_GET_CONTEXT(ctx);
|
|
1770
1886
|
|
|
1771
|
-
/* is someone else waiting to
|
|
1887
|
+
/* is someone else waiting to close a device? if so, don't let this thread
|
|
1772
1888
|
* start event handling -- indicate that event handling is happening */
|
|
1773
|
-
usbi_mutex_lock(&ctx->
|
|
1774
|
-
r = ctx->
|
|
1775
|
-
usbi_mutex_unlock(&ctx->
|
|
1889
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
1890
|
+
r = ctx->device_close;
|
|
1891
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
1776
1892
|
if (r) {
|
|
1777
|
-
usbi_dbg("someone else is
|
|
1893
|
+
usbi_dbg("someone else is closing a device");
|
|
1778
1894
|
return 1;
|
|
1779
1895
|
}
|
|
1780
1896
|
|
|
1781
1897
|
return ctx->event_handler_active;
|
|
1782
1898
|
}
|
|
1783
1899
|
|
|
1784
|
-
/** \ingroup
|
|
1900
|
+
/** \ingroup libusb_poll
|
|
1901
|
+
* Interrupt any active thread that is handling events. This is mainly useful
|
|
1902
|
+
* for interrupting a dedicated event handling thread when an application
|
|
1903
|
+
* wishes to call libusb_exit().
|
|
1904
|
+
*
|
|
1905
|
+
* Since version 1.0.21, \ref LIBUSB_API_VERSION >= 0x01000105
|
|
1906
|
+
*
|
|
1907
|
+
* \param ctx the context to operate on, or NULL for the default context
|
|
1908
|
+
* \ref libusb_mtasync
|
|
1909
|
+
*/
|
|
1910
|
+
void API_EXPORTED libusb_interrupt_event_handler(libusb_context *ctx)
|
|
1911
|
+
{
|
|
1912
|
+
int pending_events;
|
|
1913
|
+
USBI_GET_CONTEXT(ctx);
|
|
1914
|
+
|
|
1915
|
+
usbi_dbg("");
|
|
1916
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
1917
|
+
|
|
1918
|
+
pending_events = usbi_pending_events(ctx);
|
|
1919
|
+
ctx->event_flags |= USBI_EVENT_USER_INTERRUPT;
|
|
1920
|
+
if (!pending_events)
|
|
1921
|
+
usbi_signal_event(ctx);
|
|
1922
|
+
|
|
1923
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
/** \ingroup libusb_poll
|
|
1785
1927
|
* Acquire the event waiters lock. This lock is designed to be obtained under
|
|
1786
1928
|
* the situation where you want to be aware when events are completed, but
|
|
1787
1929
|
* some other thread is event handling so calling libusb_handle_events() is not
|
|
@@ -1798,7 +1940,7 @@ int API_EXPORTED libusb_event_handler_active(libusb_context *ctx)
|
|
|
1798
1940
|
* locking.
|
|
1799
1941
|
*
|
|
1800
1942
|
* \param ctx the context to operate on, or NULL for the default context
|
|
1801
|
-
* \ref
|
|
1943
|
+
* \ref libusb_mtasync
|
|
1802
1944
|
*/
|
|
1803
1945
|
void API_EXPORTED libusb_lock_event_waiters(libusb_context *ctx)
|
|
1804
1946
|
{
|
|
@@ -1806,10 +1948,10 @@ void API_EXPORTED libusb_lock_event_waiters(libusb_context *ctx)
|
|
|
1806
1948
|
usbi_mutex_lock(&ctx->event_waiters_lock);
|
|
1807
1949
|
}
|
|
1808
1950
|
|
|
1809
|
-
/** \ingroup
|
|
1951
|
+
/** \ingroup libusb_poll
|
|
1810
1952
|
* Release the event waiters lock.
|
|
1811
1953
|
* \param ctx the context to operate on, or NULL for the default context
|
|
1812
|
-
* \ref
|
|
1954
|
+
* \ref libusb_mtasync
|
|
1813
1955
|
*/
|
|
1814
1956
|
void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx)
|
|
1815
1957
|
{
|
|
@@ -1817,7 +1959,7 @@ void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx)
|
|
|
1817
1959
|
usbi_mutex_unlock(&ctx->event_waiters_lock);
|
|
1818
1960
|
}
|
|
1819
1961
|
|
|
1820
|
-
/** \ingroup
|
|
1962
|
+
/** \ingroup libusb_poll
|
|
1821
1963
|
* Wait for another thread to signal completion of an event. Must be called
|
|
1822
1964
|
* with the event waiters lock held, see libusb_lock_event_waiters().
|
|
1823
1965
|
*
|
|
@@ -1840,11 +1982,10 @@ void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx)
|
|
|
1840
1982
|
* indicates unlimited timeout.
|
|
1841
1983
|
* \returns 0 after a transfer completes or another thread stops event handling
|
|
1842
1984
|
* \returns 1 if the timeout expired
|
|
1843
|
-
* \ref
|
|
1985
|
+
* \ref libusb_mtasync
|
|
1844
1986
|
*/
|
|
1845
1987
|
int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
|
|
1846
1988
|
{
|
|
1847
|
-
struct timespec timeout;
|
|
1848
1989
|
int r;
|
|
1849
1990
|
|
|
1850
1991
|
USBI_GET_CONTEXT(ctx);
|
|
@@ -1853,22 +1994,13 @@ int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
|
|
|
1853
1994
|
return 0;
|
|
1854
1995
|
}
|
|
1855
1996
|
|
|
1856
|
-
r = usbi_backend->clock_gettime(USBI_CLOCK_REALTIME, &timeout);
|
|
1857
|
-
if (r < 0) {
|
|
1858
|
-
usbi_err(ctx, "failed to read realtime clock, error %d", errno);
|
|
1859
|
-
return LIBUSB_ERROR_OTHER;
|
|
1860
|
-
}
|
|
1861
|
-
|
|
1862
|
-
timeout.tv_sec += tv->tv_sec;
|
|
1863
|
-
timeout.tv_nsec += tv->tv_usec * 1000;
|
|
1864
|
-
while (timeout.tv_nsec >= 1000000000) {
|
|
1865
|
-
timeout.tv_nsec -= 1000000000;
|
|
1866
|
-
timeout.tv_sec++;
|
|
1867
|
-
}
|
|
1868
|
-
|
|
1869
1997
|
r = usbi_cond_timedwait(&ctx->event_waiters_cond,
|
|
1870
|
-
&ctx->event_waiters_lock,
|
|
1871
|
-
|
|
1998
|
+
&ctx->event_waiters_lock, tv);
|
|
1999
|
+
|
|
2000
|
+
if (r < 0)
|
|
2001
|
+
return r;
|
|
2002
|
+
else
|
|
2003
|
+
return (r == ETIMEDOUT);
|
|
1872
2004
|
}
|
|
1873
2005
|
|
|
1874
2006
|
static void handle_timeout(struct usbi_transfer *itransfer)
|
|
@@ -1877,9 +2009,11 @@ static void handle_timeout(struct usbi_transfer *itransfer)
|
|
|
1877
2009
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
1878
2010
|
int r;
|
|
1879
2011
|
|
|
1880
|
-
itransfer->
|
|
2012
|
+
itransfer->timeout_flags |= USBI_TRANSFER_TIMEOUT_HANDLED;
|
|
1881
2013
|
r = libusb_cancel_transfer(transfer);
|
|
1882
|
-
if (r
|
|
2014
|
+
if (r == LIBUSB_SUCCESS)
|
|
2015
|
+
itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
|
|
2016
|
+
else
|
|
1883
2017
|
usbi_warn(TRANSFER_CTX(transfer),
|
|
1884
2018
|
"async cancel failed %d errno=%d", r, errno);
|
|
1885
2019
|
}
|
|
@@ -1895,7 +2029,7 @@ static int handle_timeouts_locked(struct libusb_context *ctx)
|
|
|
1895
2029
|
return 0;
|
|
1896
2030
|
|
|
1897
2031
|
/* get current time */
|
|
1898
|
-
r = usbi_backend
|
|
2032
|
+
r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, &systime_ts);
|
|
1899
2033
|
if (r < 0)
|
|
1900
2034
|
return r;
|
|
1901
2035
|
|
|
@@ -1911,7 +2045,7 @@ static int handle_timeouts_locked(struct libusb_context *ctx)
|
|
|
1911
2045
|
return 0;
|
|
1912
2046
|
|
|
1913
2047
|
/* ignore timeouts we've already handled */
|
|
1914
|
-
if (transfer->
|
|
2048
|
+
if (transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
|
|
1915
2049
|
continue;
|
|
1916
2050
|
|
|
1917
2051
|
/* if transfer has non-expired timeout, nothing more to do */
|
|
@@ -1968,33 +2102,44 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
|
|
|
1968
2102
|
struct pollfd *fds = NULL;
|
|
1969
2103
|
int i = -1;
|
|
1970
2104
|
int timeout_ms;
|
|
1971
|
-
|
|
2105
|
+
|
|
2106
|
+
/* prevent attempts to recursively handle events (e.g. calling into
|
|
2107
|
+
* libusb_handle_events() from within a hotplug or transfer callback) */
|
|
2108
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
2109
|
+
r = 0;
|
|
2110
|
+
if (usbi_handling_events(ctx))
|
|
2111
|
+
r = LIBUSB_ERROR_BUSY;
|
|
2112
|
+
else
|
|
2113
|
+
usbi_start_event_handling(ctx);
|
|
2114
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
2115
|
+
|
|
2116
|
+
if (r)
|
|
2117
|
+
return r;
|
|
1972
2118
|
|
|
1973
2119
|
/* there are certain fds that libusb uses internally, currently:
|
|
1974
2120
|
*
|
|
1975
|
-
* 1)
|
|
1976
|
-
* 2)
|
|
1977
|
-
* 3) timerfd
|
|
2121
|
+
* 1) event pipe
|
|
2122
|
+
* 2) timerfd
|
|
1978
2123
|
*
|
|
1979
2124
|
* the backend will never need to attempt to handle events on these fds, so
|
|
1980
2125
|
* we determine how many fds are in use internally for this context and when
|
|
1981
2126
|
* handle_events() is called in the backend, the pollfd list and count will
|
|
1982
2127
|
* be adjusted to skip over these internal fds */
|
|
1983
2128
|
if (usbi_using_timerfd(ctx))
|
|
1984
|
-
internal_nfds = 3;
|
|
1985
|
-
else
|
|
1986
2129
|
internal_nfds = 2;
|
|
2130
|
+
else
|
|
2131
|
+
internal_nfds = 1;
|
|
1987
2132
|
|
|
1988
2133
|
/* only reallocate the poll fds when the list of poll fds has been modified
|
|
1989
2134
|
* since the last poll, otherwise reuse them to save the additional overhead */
|
|
1990
|
-
usbi_mutex_lock(&ctx->
|
|
1991
|
-
|
|
2135
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
2136
|
+
/* clean up removed poll fds */
|
|
2137
|
+
cleanup_removed_pollfds(ctx);
|
|
2138
|
+
if (ctx->event_flags & USBI_EVENT_POLLFDS_MODIFIED) {
|
|
1992
2139
|
usbi_dbg("poll fds modified, reallocating");
|
|
1993
2140
|
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
ctx->pollfds = NULL;
|
|
1997
|
-
}
|
|
2141
|
+
free(ctx->pollfds);
|
|
2142
|
+
ctx->pollfds = NULL;
|
|
1998
2143
|
|
|
1999
2144
|
/* sanity check - it is invalid for a context to have fewer than the
|
|
2000
2145
|
* required internal fds (memory corruption?) */
|
|
@@ -2002,8 +2147,9 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
|
|
|
2002
2147
|
|
|
2003
2148
|
ctx->pollfds = calloc(ctx->pollfds_cnt, sizeof(*ctx->pollfds));
|
|
2004
2149
|
if (!ctx->pollfds) {
|
|
2005
|
-
usbi_mutex_unlock(&ctx->
|
|
2006
|
-
|
|
2150
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
2151
|
+
r = LIBUSB_ERROR_NO_MEM;
|
|
2152
|
+
goto done;
|
|
2007
2153
|
}
|
|
2008
2154
|
|
|
2009
2155
|
list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) {
|
|
@@ -2014,11 +2160,17 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
|
|
|
2014
2160
|
}
|
|
2015
2161
|
|
|
2016
2162
|
/* reset the flag now that we have the updated list */
|
|
2017
|
-
ctx->
|
|
2163
|
+
ctx->event_flags &= ~USBI_EVENT_POLLFDS_MODIFIED;
|
|
2164
|
+
|
|
2165
|
+
/* if no further pending events, clear the event pipe so that we do
|
|
2166
|
+
* not immediately return from poll */
|
|
2167
|
+
if (!usbi_pending_events(ctx))
|
|
2168
|
+
usbi_clear_event(ctx);
|
|
2018
2169
|
}
|
|
2019
2170
|
fds = ctx->pollfds;
|
|
2020
2171
|
nfds = ctx->pollfds_cnt;
|
|
2021
|
-
|
|
2172
|
+
usbi_inc_fds_ref(fds, nfds);
|
|
2173
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
2022
2174
|
|
|
2023
2175
|
timeout_ms = (int)(tv->tv_sec * 1000) + (tv->tv_usec / 1000);
|
|
2024
2176
|
|
|
@@ -2026,89 +2178,145 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
|
|
|
2026
2178
|
if (tv->tv_usec % 1000)
|
|
2027
2179
|
timeout_ms++;
|
|
2028
2180
|
|
|
2029
|
-
|
|
2030
|
-
usbi_dbg("poll() %d fds with timeout in %dms", nfds, timeout_ms);
|
|
2181
|
+
usbi_dbg("poll() %d fds with timeout in %dms", (int)nfds, timeout_ms);
|
|
2031
2182
|
r = usbi_poll(fds, nfds, timeout_ms);
|
|
2032
2183
|
usbi_dbg("poll() returned %d", r);
|
|
2033
|
-
if (r == 0)
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2184
|
+
if (r == 0) {
|
|
2185
|
+
r = handle_timeouts(ctx);
|
|
2186
|
+
goto done;
|
|
2187
|
+
} else if (r == -1 && errno == EINTR) {
|
|
2188
|
+
r = LIBUSB_ERROR_INTERRUPTED;
|
|
2189
|
+
goto done;
|
|
2190
|
+
} else if (r < 0) {
|
|
2191
|
+
usbi_err(ctx, "poll failed %d err=%d", r, errno);
|
|
2192
|
+
r = LIBUSB_ERROR_IO;
|
|
2193
|
+
goto done;
|
|
2040
2194
|
}
|
|
2041
2195
|
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
/* fd[0] is always the ctrl pipe */
|
|
2196
|
+
/* fds[0] is always the event pipe */
|
|
2045
2197
|
if (fds[0].revents) {
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2198
|
+
struct list_head hotplug_msgs;
|
|
2199
|
+
struct usbi_transfer *itransfer;
|
|
2200
|
+
int hotplug_cb_deregistered = 0;
|
|
2201
|
+
int ret = 0;
|
|
2050
2202
|
|
|
2051
|
-
|
|
2052
|
-
goto handled;
|
|
2053
|
-
}
|
|
2203
|
+
list_init(&hotplug_msgs);
|
|
2054
2204
|
|
|
2055
|
-
|
|
2056
|
-
if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && fds[1].revents) {
|
|
2057
|
-
libusb_hotplug_message message;
|
|
2058
|
-
ssize_t ret;
|
|
2205
|
+
usbi_dbg("caught a fish on the event pipe");
|
|
2059
2206
|
|
|
2060
|
-
|
|
2061
|
-
|
|
2207
|
+
/* take the the event data lock while processing events */
|
|
2208
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
2062
2209
|
|
|
2063
|
-
/*
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2210
|
+
/* check if someone added a new poll fd */
|
|
2211
|
+
if (ctx->event_flags & USBI_EVENT_POLLFDS_MODIFIED)
|
|
2212
|
+
usbi_dbg("someone updated the poll fds");
|
|
2213
|
+
|
|
2214
|
+
if (ctx->event_flags & USBI_EVENT_USER_INTERRUPT) {
|
|
2215
|
+
usbi_dbg("someone purposely interrupted");
|
|
2216
|
+
ctx->event_flags &= ~USBI_EVENT_USER_INTERRUPT;
|
|
2070
2217
|
}
|
|
2071
2218
|
|
|
2072
|
-
|
|
2219
|
+
if (ctx->event_flags & USBI_EVENT_HOTPLUG_CB_DEREGISTERED) {
|
|
2220
|
+
usbi_dbg("someone unregistered a hotplug cb");
|
|
2221
|
+
ctx->event_flags &= ~USBI_EVENT_HOTPLUG_CB_DEREGISTERED;
|
|
2222
|
+
hotplug_cb_deregistered = 1;
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
/* check if someone is closing a device */
|
|
2226
|
+
if (ctx->device_close)
|
|
2227
|
+
usbi_dbg("someone is closing a device");
|
|
2228
|
+
|
|
2229
|
+
/* check for any pending hotplug messages */
|
|
2230
|
+
if (!list_empty(&ctx->hotplug_msgs)) {
|
|
2231
|
+
usbi_dbg("hotplug message received");
|
|
2232
|
+
list_cut(&hotplug_msgs, &ctx->hotplug_msgs);
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2235
|
+
/* complete any pending transfers */
|
|
2236
|
+
while (ret == 0 && !list_empty(&ctx->completed_transfers)) {
|
|
2237
|
+
itransfer = list_first_entry(&ctx->completed_transfers, struct usbi_transfer, completed_list);
|
|
2238
|
+
list_del(&itransfer->completed_list);
|
|
2239
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
2240
|
+
ret = usbi_backend.handle_transfer_completion(itransfer);
|
|
2241
|
+
if (ret)
|
|
2242
|
+
usbi_err(ctx, "backend handle_transfer_completion failed with error %d", ret);
|
|
2243
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
/* if no further pending events, clear the event pipe */
|
|
2247
|
+
if (!usbi_pending_events(ctx))
|
|
2248
|
+
usbi_clear_event(ctx);
|
|
2249
|
+
|
|
2250
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
2251
|
+
|
|
2252
|
+
if (hotplug_cb_deregistered)
|
|
2253
|
+
usbi_hotplug_deregister(ctx, 0);
|
|
2073
2254
|
|
|
2074
|
-
/* the
|
|
2075
|
-
|
|
2076
|
-
|
|
2255
|
+
/* process the hotplug messages, if any */
|
|
2256
|
+
while (!list_empty(&hotplug_msgs)) {
|
|
2257
|
+
struct libusb_hotplug_message *message =
|
|
2258
|
+
list_first_entry(&hotplug_msgs, struct libusb_hotplug_message, list);
|
|
2259
|
+
|
|
2260
|
+
usbi_hotplug_match(ctx, message->device, message->event);
|
|
2261
|
+
|
|
2262
|
+
/* the device left, dereference the device */
|
|
2263
|
+
if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == message->event)
|
|
2264
|
+
libusb_unref_device(message->device);
|
|
2265
|
+
|
|
2266
|
+
list_del(&message->list);
|
|
2267
|
+
free(message);
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
if (ret) {
|
|
2271
|
+
/* return error code */
|
|
2272
|
+
r = ret;
|
|
2273
|
+
goto done;
|
|
2274
|
+
}
|
|
2077
2275
|
|
|
2078
2276
|
if (0 == --r)
|
|
2079
|
-
goto
|
|
2080
|
-
}
|
|
2277
|
+
goto done;
|
|
2278
|
+
}
|
|
2081
2279
|
|
|
2082
2280
|
#ifdef USBI_TIMERFD_AVAILABLE
|
|
2083
|
-
/* on timerfd configurations, fds[
|
|
2084
|
-
if (usbi_using_timerfd(ctx) && fds[
|
|
2281
|
+
/* on timerfd configurations, fds[1] is the timerfd */
|
|
2282
|
+
if (usbi_using_timerfd(ctx) && fds[1].revents) {
|
|
2085
2283
|
/* timerfd indicates that a timeout has expired */
|
|
2086
2284
|
int ret;
|
|
2087
2285
|
usbi_dbg("timerfd triggered");
|
|
2088
|
-
special_event = 1;
|
|
2089
2286
|
|
|
2090
2287
|
ret = handle_timerfd_trigger(ctx);
|
|
2091
2288
|
if (ret < 0) {
|
|
2092
2289
|
/* return error code */
|
|
2093
2290
|
r = ret;
|
|
2094
|
-
goto
|
|
2291
|
+
goto done;
|
|
2095
2292
|
}
|
|
2096
2293
|
|
|
2097
2294
|
if (0 == --r)
|
|
2098
|
-
goto
|
|
2295
|
+
goto done;
|
|
2099
2296
|
}
|
|
2100
2297
|
#endif
|
|
2101
2298
|
|
|
2102
|
-
|
|
2299
|
+
list_for_each_entry(ipollfd, &ctx->removed_ipollfds, list, struct usbi_pollfd) {
|
|
2300
|
+
for (i = internal_nfds ; i < nfds ; ++i) {
|
|
2301
|
+
if (ipollfd->pollfd.fd == fds[i].fd) {
|
|
2302
|
+
/* pollfd was removed between the creation of the fd
|
|
2303
|
+
* array and here. remove any triggered revent as
|
|
2304
|
+
* it is no longer relevant */
|
|
2305
|
+
usbi_dbg("pollfd %d was removed. ignoring raised events",
|
|
2306
|
+
fds[i].fd);
|
|
2307
|
+
fds[i].revents = 0;
|
|
2308
|
+
break;
|
|
2309
|
+
}
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
r = usbi_backend.handle_events(ctx, fds + internal_nfds, nfds - internal_nfds, r);
|
|
2103
2314
|
if (r)
|
|
2104
2315
|
usbi_err(ctx, "backend handle_events failed with error %d", r);
|
|
2105
2316
|
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
goto redo_poll;
|
|
2110
|
-
}
|
|
2111
|
-
|
|
2317
|
+
done:
|
|
2318
|
+
usbi_end_event_handling(ctx);
|
|
2319
|
+
usbi_dec_fds_ref(fds, nfds);
|
|
2112
2320
|
return r;
|
|
2113
2321
|
}
|
|
2114
2322
|
|
|
@@ -2139,7 +2347,7 @@ static int get_next_timeout(libusb_context *ctx, struct timeval *tv,
|
|
|
2139
2347
|
return 0;
|
|
2140
2348
|
}
|
|
2141
2349
|
|
|
2142
|
-
/** \ingroup
|
|
2350
|
+
/** \ingroup libusb_poll
|
|
2143
2351
|
* Handle any pending events.
|
|
2144
2352
|
*
|
|
2145
2353
|
* libusb determines "pending events" by checking if any timeouts have expired
|
|
@@ -2163,7 +2371,7 @@ static int get_next_timeout(libusb_context *ctx, struct timeval *tv,
|
|
|
2163
2371
|
* timeval struct for non-blocking mode
|
|
2164
2372
|
* \param completed pointer to completion integer to check, or NULL
|
|
2165
2373
|
* \returns 0 on success, or a LIBUSB_ERROR code on failure
|
|
2166
|
-
* \ref
|
|
2374
|
+
* \ref libusb_mtasync
|
|
2167
2375
|
*/
|
|
2168
2376
|
int API_EXPORTED libusb_handle_events_timeout_completed(libusb_context *ctx,
|
|
2169
2377
|
struct timeval *tv, int *completed)
|
|
@@ -2218,7 +2426,7 @@ already_done:
|
|
|
2218
2426
|
return 0;
|
|
2219
2427
|
}
|
|
2220
2428
|
|
|
2221
|
-
/** \ingroup
|
|
2429
|
+
/** \ingroup libusb_poll
|
|
2222
2430
|
* Handle any pending events
|
|
2223
2431
|
*
|
|
2224
2432
|
* Like libusb_handle_events_timeout_completed(), but without the completed
|
|
@@ -2240,7 +2448,7 @@ int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx,
|
|
|
2240
2448
|
return libusb_handle_events_timeout_completed(ctx, tv, NULL);
|
|
2241
2449
|
}
|
|
2242
2450
|
|
|
2243
|
-
/** \ingroup
|
|
2451
|
+
/** \ingroup libusb_poll
|
|
2244
2452
|
* Handle any pending events in blocking mode. There is currently a timeout
|
|
2245
2453
|
* hardcoded at 60 seconds but we plan to make it unlimited in future. For
|
|
2246
2454
|
* finer control over whether this function is blocking or non-blocking, or
|
|
@@ -2262,7 +2470,7 @@ int API_EXPORTED libusb_handle_events(libusb_context *ctx)
|
|
|
2262
2470
|
return libusb_handle_events_timeout_completed(ctx, &tv, NULL);
|
|
2263
2471
|
}
|
|
2264
2472
|
|
|
2265
|
-
/** \ingroup
|
|
2473
|
+
/** \ingroup libusb_poll
|
|
2266
2474
|
* Handle any pending events in blocking mode.
|
|
2267
2475
|
*
|
|
2268
2476
|
* Like libusb_handle_events(), with the addition of a completed parameter
|
|
@@ -2274,7 +2482,7 @@ int API_EXPORTED libusb_handle_events(libusb_context *ctx)
|
|
|
2274
2482
|
* \param ctx the context to operate on, or NULL for the default context
|
|
2275
2483
|
* \param completed pointer to completion integer to check, or NULL
|
|
2276
2484
|
* \returns 0 on success, or a LIBUSB_ERROR code on failure
|
|
2277
|
-
* \ref
|
|
2485
|
+
* \ref libusb_mtasync
|
|
2278
2486
|
*/
|
|
2279
2487
|
int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx,
|
|
2280
2488
|
int *completed)
|
|
@@ -2285,7 +2493,7 @@ int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx,
|
|
|
2285
2493
|
return libusb_handle_events_timeout_completed(ctx, &tv, completed);
|
|
2286
2494
|
}
|
|
2287
2495
|
|
|
2288
|
-
/** \ingroup
|
|
2496
|
+
/** \ingroup libusb_poll
|
|
2289
2497
|
* Handle any pending events by polling file descriptors, without checking if
|
|
2290
2498
|
* any other threads are already doing so. Must be called with the event lock
|
|
2291
2499
|
* held, see libusb_lock_events().
|
|
@@ -2300,7 +2508,7 @@ int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx,
|
|
|
2300
2508
|
* \param tv the maximum time to block waiting for events, or zero for
|
|
2301
2509
|
* non-blocking mode
|
|
2302
2510
|
* \returns 0 on success, or a LIBUSB_ERROR code on failure
|
|
2303
|
-
* \ref
|
|
2511
|
+
* \ref libusb_mtasync
|
|
2304
2512
|
*/
|
|
2305
2513
|
int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx,
|
|
2306
2514
|
struct timeval *tv)
|
|
@@ -2318,12 +2526,12 @@ int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx,
|
|
|
2318
2526
|
return handle_events(ctx, &poll_timeout);
|
|
2319
2527
|
}
|
|
2320
2528
|
|
|
2321
|
-
/** \ingroup
|
|
2529
|
+
/** \ingroup libusb_poll
|
|
2322
2530
|
* Determines whether your application must apply special timing considerations
|
|
2323
2531
|
* when monitoring libusb's file descriptors.
|
|
2324
2532
|
*
|
|
2325
2533
|
* This function is only useful for applications which retrieve and poll
|
|
2326
|
-
* libusb's file descriptors in their own main loop (\ref
|
|
2534
|
+
* libusb's file descriptors in their own main loop (\ref libusb_pollmain).
|
|
2327
2535
|
*
|
|
2328
2536
|
* Ordinarily, libusb's event handler needs to be called into at specific
|
|
2329
2537
|
* moments in time (in addition to times when there is activity on the file
|
|
@@ -2344,7 +2552,7 @@ int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx,
|
|
|
2344
2552
|
* \returns 0 if you must call into libusb at times determined by
|
|
2345
2553
|
* libusb_get_next_timeout(), or 1 if all timeout events are handled internally
|
|
2346
2554
|
* or through regular activity on the file descriptors.
|
|
2347
|
-
* \ref
|
|
2555
|
+
* \ref libusb_pollmain "Polling libusb file descriptors for event handling"
|
|
2348
2556
|
*/
|
|
2349
2557
|
int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx)
|
|
2350
2558
|
{
|
|
@@ -2352,12 +2560,12 @@ int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx)
|
|
|
2352
2560
|
USBI_GET_CONTEXT(ctx);
|
|
2353
2561
|
return usbi_using_timerfd(ctx);
|
|
2354
2562
|
#else
|
|
2355
|
-
(
|
|
2563
|
+
UNUSED(ctx);
|
|
2356
2564
|
return 0;
|
|
2357
2565
|
#endif
|
|
2358
2566
|
}
|
|
2359
2567
|
|
|
2360
|
-
/** \ingroup
|
|
2568
|
+
/** \ingroup libusb_poll
|
|
2361
2569
|
* Determine the next internal timeout that libusb needs to handle. You only
|
|
2362
2570
|
* need to use this function if you are calling poll() or select() or similar
|
|
2363
2571
|
* on libusb's file descriptors yourself - you do not need to use it if you
|
|
@@ -2391,9 +2599,8 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
|
|
|
2391
2599
|
struct usbi_transfer *transfer;
|
|
2392
2600
|
struct timespec cur_ts;
|
|
2393
2601
|
struct timeval cur_tv;
|
|
2394
|
-
struct timeval
|
|
2602
|
+
struct timeval next_timeout = { 0, 0 };
|
|
2395
2603
|
int r;
|
|
2396
|
-
int found = 0;
|
|
2397
2604
|
|
|
2398
2605
|
USBI_GET_CONTEXT(ctx);
|
|
2399
2606
|
if (usbi_using_timerfd(ctx))
|
|
@@ -2408,44 +2615,42 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
|
|
|
2408
2615
|
|
|
2409
2616
|
/* find next transfer which hasn't already been processed as timed out */
|
|
2410
2617
|
list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
|
|
2411
|
-
if (transfer->
|
|
2618
|
+
if (transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
|
|
2412
2619
|
continue;
|
|
2413
2620
|
|
|
2414
|
-
/*
|
|
2621
|
+
/* if we've reached transfers of infinte timeout, we're done looking */
|
|
2415
2622
|
if (!timerisset(&transfer->timeout))
|
|
2416
|
-
|
|
2623
|
+
break;
|
|
2417
2624
|
|
|
2418
|
-
|
|
2625
|
+
next_timeout = transfer->timeout;
|
|
2419
2626
|
break;
|
|
2420
2627
|
}
|
|
2421
2628
|
usbi_mutex_unlock(&ctx->flying_transfers_lock);
|
|
2422
2629
|
|
|
2423
|
-
if (!
|
|
2630
|
+
if (!timerisset(&next_timeout)) {
|
|
2424
2631
|
usbi_dbg("no URB with timeout or all handled by OS; no timeout!");
|
|
2425
2632
|
return 0;
|
|
2426
2633
|
}
|
|
2427
2634
|
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts);
|
|
2635
|
+
r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts);
|
|
2431
2636
|
if (r < 0) {
|
|
2432
2637
|
usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno);
|
|
2433
2638
|
return 0;
|
|
2434
2639
|
}
|
|
2435
2640
|
TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts);
|
|
2436
2641
|
|
|
2437
|
-
if (!timercmp(&cur_tv, next_timeout, <)) {
|
|
2642
|
+
if (!timercmp(&cur_tv, &next_timeout, <)) {
|
|
2438
2643
|
usbi_dbg("first timeout already expired");
|
|
2439
2644
|
timerclear(tv);
|
|
2440
2645
|
} else {
|
|
2441
|
-
timersub(next_timeout, &cur_tv, tv);
|
|
2442
|
-
usbi_dbg("next timeout in %
|
|
2646
|
+
timersub(&next_timeout, &cur_tv, tv);
|
|
2647
|
+
usbi_dbg("next timeout in %ld.%06lds", (long)tv->tv_sec, (long)tv->tv_usec);
|
|
2443
2648
|
}
|
|
2444
2649
|
|
|
2445
2650
|
return 1;
|
|
2446
2651
|
}
|
|
2447
2652
|
|
|
2448
|
-
/** \ingroup
|
|
2653
|
+
/** \ingroup libusb_poll
|
|
2449
2654
|
* Register notification functions for file descriptor additions/removals.
|
|
2450
2655
|
* These functions will be invoked for every new or removed file descriptor
|
|
2451
2656
|
* that libusb uses as an event source.
|
|
@@ -2476,6 +2681,22 @@ void API_EXPORTED libusb_set_pollfd_notifiers(libusb_context *ctx,
|
|
|
2476
2681
|
ctx->fd_cb_user_data = user_data;
|
|
2477
2682
|
}
|
|
2478
2683
|
|
|
2684
|
+
/*
|
|
2685
|
+
* Interrupt the iteration of the event handling thread, so that it picks
|
|
2686
|
+
* up the fd change. Callers of this function must hold the event_data_lock.
|
|
2687
|
+
*/
|
|
2688
|
+
static void usbi_fd_notification(struct libusb_context *ctx)
|
|
2689
|
+
{
|
|
2690
|
+
int pending_events;
|
|
2691
|
+
|
|
2692
|
+
/* Record that there is a new poll fd.
|
|
2693
|
+
* Only signal an event if there are no prior pending events. */
|
|
2694
|
+
pending_events = usbi_pending_events(ctx);
|
|
2695
|
+
ctx->event_flags |= USBI_EVENT_POLLFDS_MODIFIED;
|
|
2696
|
+
if (!pending_events)
|
|
2697
|
+
usbi_signal_event(ctx);
|
|
2698
|
+
}
|
|
2699
|
+
|
|
2479
2700
|
/* Add a file descriptor to the list of file descriptors to be monitored.
|
|
2480
2701
|
* events should be specified as a bitmask of events passed to poll(), e.g.
|
|
2481
2702
|
* POLLIN and/or POLLOUT. */
|
|
@@ -2488,11 +2709,11 @@ int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events)
|
|
|
2488
2709
|
usbi_dbg("add fd %d events %d", fd, events);
|
|
2489
2710
|
ipollfd->pollfd.fd = fd;
|
|
2490
2711
|
ipollfd->pollfd.events = events;
|
|
2491
|
-
usbi_mutex_lock(&ctx->
|
|
2712
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
2492
2713
|
list_add_tail(&ipollfd->list, &ctx->ipollfds);
|
|
2493
2714
|
ctx->pollfds_cnt++;
|
|
2494
|
-
ctx
|
|
2495
|
-
usbi_mutex_unlock(&ctx->
|
|
2715
|
+
usbi_fd_notification(ctx);
|
|
2716
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
2496
2717
|
|
|
2497
2718
|
if (ctx->fd_added_cb)
|
|
2498
2719
|
ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data);
|
|
@@ -2506,7 +2727,7 @@ void usbi_remove_pollfd(struct libusb_context *ctx, int fd)
|
|
|
2506
2727
|
int found = 0;
|
|
2507
2728
|
|
|
2508
2729
|
usbi_dbg("remove fd %d", fd);
|
|
2509
|
-
usbi_mutex_lock(&ctx->
|
|
2730
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
2510
2731
|
list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd)
|
|
2511
2732
|
if (ipollfd->pollfd.fd == fd) {
|
|
2512
2733
|
found = 1;
|
|
@@ -2515,25 +2736,26 @@ void usbi_remove_pollfd(struct libusb_context *ctx, int fd)
|
|
|
2515
2736
|
|
|
2516
2737
|
if (!found) {
|
|
2517
2738
|
usbi_dbg("couldn't find fd %d to remove", fd);
|
|
2518
|
-
usbi_mutex_unlock(&ctx->
|
|
2739
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
2519
2740
|
return;
|
|
2520
2741
|
}
|
|
2521
2742
|
|
|
2522
2743
|
list_del(&ipollfd->list);
|
|
2744
|
+
list_add_tail(&ipollfd->list, &ctx->removed_ipollfds);
|
|
2523
2745
|
ctx->pollfds_cnt--;
|
|
2524
|
-
ctx
|
|
2525
|
-
usbi_mutex_unlock(&ctx->
|
|
2526
|
-
|
|
2746
|
+
usbi_fd_notification(ctx);
|
|
2747
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
2748
|
+
|
|
2527
2749
|
if (ctx->fd_removed_cb)
|
|
2528
2750
|
ctx->fd_removed_cb(fd, ctx->fd_cb_user_data);
|
|
2529
2751
|
}
|
|
2530
2752
|
|
|
2531
|
-
/** \ingroup
|
|
2753
|
+
/** \ingroup libusb_poll
|
|
2532
2754
|
* Retrieve a list of file descriptors that should be polled by your main loop
|
|
2533
2755
|
* as libusb event sources.
|
|
2534
2756
|
*
|
|
2535
|
-
* The returned list is NULL-terminated and should be freed with
|
|
2536
|
-
* done. The actual list contents must not be touched.
|
|
2757
|
+
* The returned list is NULL-terminated and should be freed with libusb_free_pollfds()
|
|
2758
|
+
* when done. The actual list contents must not be touched.
|
|
2537
2759
|
*
|
|
2538
2760
|
* As file descriptors are a Unix-specific concept, this function is not
|
|
2539
2761
|
* available on Windows and will always return NULL.
|
|
@@ -2553,7 +2775,7 @@ const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds(
|
|
|
2553
2775
|
size_t i = 0;
|
|
2554
2776
|
USBI_GET_CONTEXT(ctx);
|
|
2555
2777
|
|
|
2556
|
-
usbi_mutex_lock(&ctx->
|
|
2778
|
+
usbi_mutex_lock(&ctx->event_data_lock);
|
|
2557
2779
|
|
|
2558
2780
|
ret = calloc(ctx->pollfds_cnt + 1, sizeof(struct libusb_pollfd *));
|
|
2559
2781
|
if (!ret)
|
|
@@ -2564,7 +2786,7 @@ const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds(
|
|
|
2564
2786
|
ret[ctx->pollfds_cnt] = NULL;
|
|
2565
2787
|
|
|
2566
2788
|
out:
|
|
2567
|
-
usbi_mutex_unlock(&ctx->
|
|
2789
|
+
usbi_mutex_unlock(&ctx->event_data_lock);
|
|
2568
2790
|
return (const struct libusb_pollfd **) ret;
|
|
2569
2791
|
#else
|
|
2570
2792
|
usbi_err(ctx, "external polling of libusb's internal descriptors "\
|
|
@@ -2573,50 +2795,61 @@ out:
|
|
|
2573
2795
|
#endif
|
|
2574
2796
|
}
|
|
2575
2797
|
|
|
2798
|
+
/** \ingroup libusb_poll
|
|
2799
|
+
* Free a list of libusb_pollfd structures. This should be called for all
|
|
2800
|
+
* pollfd lists allocated with libusb_get_pollfds().
|
|
2801
|
+
*
|
|
2802
|
+
* Since version 1.0.20, \ref LIBUSB_API_VERSION >= 0x01000104
|
|
2803
|
+
*
|
|
2804
|
+
* It is legal to call this function with a NULL pollfd list. In this case,
|
|
2805
|
+
* the function will simply do nothing.
|
|
2806
|
+
*
|
|
2807
|
+
* \param pollfds the list of libusb_pollfd structures to free
|
|
2808
|
+
*/
|
|
2809
|
+
void API_EXPORTED libusb_free_pollfds(const struct libusb_pollfd **pollfds)
|
|
2810
|
+
{
|
|
2811
|
+
free((void *)pollfds);
|
|
2812
|
+
}
|
|
2813
|
+
|
|
2576
2814
|
/* Backends may call this from handle_events to report disconnection of a
|
|
2577
2815
|
* device. This function ensures transfers get cancelled appropriately.
|
|
2578
2816
|
* Callers of this function must hold the events_lock.
|
|
2579
2817
|
*/
|
|
2580
|
-
void usbi_handle_disconnect(struct libusb_device_handle *
|
|
2818
|
+
void usbi_handle_disconnect(struct libusb_device_handle *dev_handle)
|
|
2581
2819
|
{
|
|
2582
2820
|
struct usbi_transfer *cur;
|
|
2583
2821
|
struct usbi_transfer *to_cancel;
|
|
2584
2822
|
|
|
2585
2823
|
usbi_dbg("device %d.%d",
|
|
2586
|
-
|
|
2824
|
+
dev_handle->dev->bus_number, dev_handle->dev->device_address);
|
|
2587
2825
|
|
|
2588
2826
|
/* terminate all pending transfers with the LIBUSB_TRANSFER_NO_DEVICE
|
|
2589
2827
|
* status code.
|
|
2590
2828
|
*
|
|
2591
|
-
*
|
|
2592
|
-
*
|
|
2593
|
-
*
|
|
2594
|
-
*
|
|
2595
|
-
*
|
|
2596
|
-
*
|
|
2597
|
-
*
|
|
2598
|
-
*
|
|
2599
|
-
*
|
|
2600
|
-
* This is safe because transfers are only removed from the
|
|
2601
|
-
* flying_transfer list by usbi_handle_transfer_completion and
|
|
2602
|
-
* libusb_close, both of which hold the events_lock while doing so,
|
|
2603
|
-
* so usbi_handle_disconnect cannot be running at the same time.
|
|
2604
|
-
*
|
|
2605
|
-
* Note that libusb_submit_transfer also removes the transfer from
|
|
2606
|
-
* the flying_transfer list on submission failure, but it keeps the
|
|
2607
|
-
* flying_transfer list locked between addition and removal, so
|
|
2608
|
-
* usbi_handle_disconnect never sees such transfers.
|
|
2829
|
+
* when we find a transfer for this device on the list, there are two
|
|
2830
|
+
* possible scenarios:
|
|
2831
|
+
* 1. the transfer is currently in-flight, in which case we terminate the
|
|
2832
|
+
* transfer here
|
|
2833
|
+
* 2. the transfer has been added to the flying transfer list by
|
|
2834
|
+
* libusb_submit_transfer, has failed to submit and
|
|
2835
|
+
* libusb_submit_transfer is waiting for us to release the
|
|
2836
|
+
* flying_transfers_lock to remove it, so we ignore it
|
|
2609
2837
|
*/
|
|
2610
2838
|
|
|
2611
2839
|
while (1) {
|
|
2612
|
-
usbi_mutex_lock(&HANDLE_CTX(handle)->flying_transfers_lock);
|
|
2613
2840
|
to_cancel = NULL;
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2841
|
+
usbi_mutex_lock(&HANDLE_CTX(dev_handle)->flying_transfers_lock);
|
|
2842
|
+
list_for_each_entry(cur, &HANDLE_CTX(dev_handle)->flying_transfers, list, struct usbi_transfer)
|
|
2843
|
+
if (USBI_TRANSFER_TO_LIBUSB_TRANSFER(cur)->dev_handle == dev_handle) {
|
|
2844
|
+
usbi_mutex_lock(&cur->lock);
|
|
2845
|
+
if (cur->state_flags & USBI_TRANSFER_IN_FLIGHT)
|
|
2846
|
+
to_cancel = cur;
|
|
2847
|
+
usbi_mutex_unlock(&cur->lock);
|
|
2848
|
+
|
|
2849
|
+
if (to_cancel)
|
|
2850
|
+
break;
|
|
2618
2851
|
}
|
|
2619
|
-
usbi_mutex_unlock(&HANDLE_CTX(
|
|
2852
|
+
usbi_mutex_unlock(&HANDLE_CTX(dev_handle)->flying_transfers_lock);
|
|
2620
2853
|
|
|
2621
2854
|
if (!to_cancel)
|
|
2622
2855
|
break;
|
|
@@ -2624,7 +2857,9 @@ void usbi_handle_disconnect(struct libusb_device_handle *handle)
|
|
|
2624
2857
|
usbi_dbg("cancelling transfer %p from disconnect",
|
|
2625
2858
|
USBI_TRANSFER_TO_LIBUSB_TRANSFER(to_cancel));
|
|
2626
2859
|
|
|
2627
|
-
|
|
2860
|
+
usbi_mutex_lock(&to_cancel->lock);
|
|
2861
|
+
usbi_backend.clear_transfer_priv(to_cancel);
|
|
2862
|
+
usbi_mutex_unlock(&to_cancel->lock);
|
|
2628
2863
|
usbi_handle_transfer_completion(to_cancel, LIBUSB_TRANSFER_NO_DEVICE);
|
|
2629
2864
|
}
|
|
2630
2865
|
|