usb 2.1.3 → 2.3.1

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.
Files changed (292) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +19 -2
  3. package/dist/index.d.ts +2 -1
  4. package/dist/index.js +3 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/usb/bindings.d.ts +4 -0
  7. package/dist/usb/device.js +5 -0
  8. package/dist/usb/device.js.map +1 -1
  9. package/dist/usb/index.js +7 -16
  10. package/dist/usb/index.js.map +1 -1
  11. package/dist/webusb/webusb-device.d.ts +0 -1
  12. package/dist/webusb/webusb-device.js +149 -243
  13. package/dist/webusb/webusb-device.js.map +1 -1
  14. package/libusb/.gitattributes +2 -6
  15. package/libusb/.private/appveyor_build.sh +22 -0
  16. package/libusb/.private/bm.sh +1 -1
  17. package/libusb/.private/ci-build.sh +67 -0
  18. package/libusb/.private/ci-container-build.sh +70 -0
  19. package/libusb/.private/post-rewrite.sh +5 -1
  20. package/libusb/.private/pre-commit.sh +5 -1
  21. package/libusb/.private/wbs.txt +4 -19
  22. package/libusb/.travis.yml +32 -23
  23. package/libusb/AUTHORS +86 -3
  24. package/libusb/ChangeLog +54 -3
  25. package/libusb/INSTALL_WIN.txt +22 -44
  26. package/libusb/Makefile.am +32 -10
  27. package/libusb/{README.md → README} +2 -2
  28. package/libusb/README.git +3 -3
  29. package/libusb/Xcode/common.xcconfig +23 -19
  30. package/libusb/Xcode/config.h +25 -13
  31. package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +511 -109
  32. package/libusb/android/README +90 -54
  33. package/libusb/android/config.h +23 -43
  34. package/libusb/android/examples/unrooted_android.c +300 -0
  35. package/libusb/android/examples/unrooted_android.h +36 -0
  36. package/libusb/android/jni/Android.mk +1 -1
  37. package/libusb/android/jni/Application.mk +16 -0
  38. package/libusb/android/jni/examples.mk +63 -29
  39. package/libusb/android/jni/libusb.mk +14 -8
  40. package/libusb/android/jni/tests.mk +13 -24
  41. package/libusb/appveyor.yml +73 -30
  42. package/libusb/autogen.sh +5 -3
  43. package/libusb/bootstrap.sh +6 -2
  44. package/libusb/configure.ac +314 -227
  45. package/libusb/doc/Makefile.in +22 -0
  46. package/libusb/doc/doxygen.cfg.in +460 -223
  47. package/libusb/examples/Makefile.am +6 -13
  48. package/libusb/examples/dpfp.c +276 -73
  49. package/libusb/examples/ezusb.c +18 -8
  50. package/libusb/examples/ezusb.h +6 -17
  51. package/libusb/examples/fxload.c +4 -5
  52. package/libusb/examples/hotplugtest.c +1 -1
  53. package/libusb/examples/sam3u_benchmark.c +59 -24
  54. package/libusb/examples/testlibusb.c +138 -104
  55. package/libusb/examples/xusb.c +26 -22
  56. package/libusb/libusb/Makefile.am +57 -70
  57. package/libusb/libusb/Makefile.am.extra +26 -0
  58. package/libusb/libusb/core.c +432 -423
  59. package/libusb/libusb/descriptor.c +365 -419
  60. package/libusb/libusb/hotplug.c +200 -104
  61. package/libusb/libusb/io.c +522 -535
  62. package/libusb/libusb/libusb-1.0.def +7 -3
  63. package/libusb/libusb/libusb-1.0.rc +1 -9
  64. package/libusb/libusb/libusb.h +302 -226
  65. package/libusb/libusb/libusbi.h +607 -316
  66. package/libusb/libusb/os/darwin_usb.c +703 -329
  67. package/libusb/libusb/os/darwin_usb.h +39 -15
  68. package/libusb/libusb/os/events_posix.c +300 -0
  69. package/libusb/libusb/os/events_posix.h +59 -0
  70. package/libusb/libusb/os/events_windows.c +214 -0
  71. package/libusb/{msvc/missing.h → libusb/os/events_windows.h} +25 -11
  72. package/libusb/libusb/os/haiku_pollfs.cpp +14 -9
  73. package/libusb/libusb/os/haiku_usb.h +12 -12
  74. package/libusb/libusb/os/haiku_usb_backend.cpp +36 -37
  75. package/libusb/libusb/os/haiku_usb_raw.cpp +80 -116
  76. package/libusb/libusb/os/linux_netlink.c +55 -63
  77. package/libusb/libusb/os/linux_udev.c +61 -69
  78. package/libusb/libusb/os/linux_usbfs.c +926 -1015
  79. package/libusb/libusb/os/linux_usbfs.h +74 -57
  80. package/libusb/libusb/os/netbsd_usb.c +103 -168
  81. package/libusb/libusb/os/null_usb.c +111 -0
  82. package/libusb/libusb/os/openbsd_usb.c +71 -120
  83. package/libusb/libusb/os/sunos_usb.c +289 -375
  84. package/libusb/libusb/os/sunos_usb.h +0 -1
  85. package/libusb/libusb/os/threads_posix.c +81 -32
  86. package/libusb/libusb/os/threads_posix.h +19 -23
  87. package/libusb/libusb/os/threads_windows.c +9 -95
  88. package/libusb/libusb/os/threads_windows.h +33 -31
  89. package/libusb/libusb/os/windows_common.c +915 -0
  90. package/libusb/libusb/os/windows_common.h +330 -42
  91. package/libusb/libusb/os/windows_usbdk.c +161 -267
  92. package/libusb/libusb/os/windows_usbdk.h +5 -2
  93. package/libusb/libusb/os/windows_winusb.c +1355 -1192
  94. package/libusb/libusb/os/windows_winusb.h +167 -167
  95. package/libusb/libusb/strerror.c +20 -30
  96. package/libusb/libusb/sync.c +20 -21
  97. package/libusb/libusb/version.h +1 -1
  98. package/libusb/libusb/version_nano.h +1 -1
  99. package/libusb/msvc/.gitattributes +3 -0
  100. package/libusb/msvc/config.h +27 -20
  101. package/libusb/msvc/{hotplugtest_2012.vcxproj → dpfp_2013.vcxproj} +14 -10
  102. package/libusb/msvc/dpfp_2013.vcxproj.filters +26 -0
  103. package/libusb/msvc/{hotplugtest_2010.vcxproj → dpfp_2015.vcxproj} +14 -9
  104. package/libusb/msvc/dpfp_2015.vcxproj.filters +26 -0
  105. package/libusb/msvc/dpfp_2017.vcxproj +106 -0
  106. package/libusb/msvc/dpfp_2017.vcxproj.filters +26 -0
  107. package/libusb/msvc/dpfp_2019.vcxproj +106 -0
  108. package/libusb/msvc/dpfp_2019.vcxproj.filters +26 -0
  109. package/libusb/msvc/dpfp_threaded_2013.vcxproj +87 -0
  110. package/libusb/msvc/dpfp_threaded_2013.vcxproj.filters +26 -0
  111. package/libusb/msvc/dpfp_threaded_2015.vcxproj +87 -0
  112. package/libusb/msvc/dpfp_threaded_2015.vcxproj.filters +26 -0
  113. package/libusb/msvc/dpfp_threaded_2017.vcxproj +106 -0
  114. package/libusb/msvc/dpfp_threaded_2017.vcxproj.filters +26 -0
  115. package/libusb/msvc/{fxload_2012.vcxproj → dpfp_threaded_2019.vcxproj} +32 -17
  116. package/libusb/msvc/dpfp_threaded_2019.vcxproj.filters +26 -0
  117. package/libusb/msvc/fxload_2013.vcxproj +6 -3
  118. package/libusb/msvc/fxload_2013.vcxproj.filters +35 -0
  119. package/libusb/msvc/fxload_2015.vcxproj +6 -3
  120. package/libusb/msvc/fxload_2015.vcxproj.filters +35 -0
  121. package/libusb/msvc/fxload_2017.vcxproj +6 -7
  122. package/libusb/msvc/fxload_2017.vcxproj.filters +35 -0
  123. package/libusb/msvc/{fxload_2010.vcxproj → fxload_2019.vcxproj} +29 -6
  124. package/libusb/msvc/fxload_2019.vcxproj.filters +35 -0
  125. package/libusb/{examples → msvc}/getopt/getopt.c +0 -0
  126. package/libusb/{examples → msvc}/getopt/getopt.h +0 -0
  127. package/libusb/{examples → msvc}/getopt/getopt1.c +0 -0
  128. package/libusb/msvc/getopt_2013.vcxproj +4 -5
  129. package/libusb/msvc/getopt_2013.vcxproj.filters +26 -0
  130. package/libusb/msvc/getopt_2015.vcxproj +4 -4
  131. package/libusb/msvc/getopt_2015.vcxproj.filters +26 -0
  132. package/libusb/msvc/getopt_2017.vcxproj +4 -10
  133. package/libusb/msvc/getopt_2017.vcxproj.filters +26 -0
  134. package/libusb/msvc/{getopt_2010.vcxproj → getopt_2019.vcxproj} +25 -5
  135. package/libusb/msvc/getopt_2019.vcxproj.filters +26 -0
  136. package/libusb/msvc/hotplugtest_2013.vcxproj +6 -3
  137. package/libusb/msvc/hotplugtest_2013.vcxproj.filters +23 -0
  138. package/libusb/msvc/hotplugtest_2015.vcxproj +6 -3
  139. package/libusb/msvc/hotplugtest_2015.vcxproj.filters +23 -0
  140. package/libusb/msvc/hotplugtest_2017.vcxproj +6 -7
  141. package/libusb/msvc/hotplugtest_2017.vcxproj.filters +23 -0
  142. package/libusb/msvc/hotplugtest_2019.vcxproj +105 -0
  143. package/libusb/msvc/hotplugtest_2019.vcxproj.filters +23 -0
  144. package/libusb/msvc/libusb_2013.sln +50 -20
  145. package/libusb/msvc/libusb_2015.sln +51 -21
  146. package/libusb/msvc/libusb_2017.sln +90 -36
  147. package/libusb/msvc/libusb_2019.sln +240 -0
  148. package/libusb/msvc/libusb_dll_2013.vcxproj +6 -9
  149. package/libusb/msvc/libusb_dll_2013.vcxproj.filters +94 -0
  150. package/libusb/msvc/libusb_dll_2015.vcxproj +6 -8
  151. package/libusb/msvc/libusb_dll_2015.vcxproj.filters +94 -0
  152. package/libusb/msvc/libusb_dll_2017.vcxproj +6 -16
  153. package/libusb/msvc/libusb_dll_2017.vcxproj.filters +94 -0
  154. package/libusb/msvc/{libusb_dll_2010.vcxproj → libusb_dll_2019.vcxproj} +27 -9
  155. package/libusb/msvc/libusb_dll_2019.vcxproj.filters +94 -0
  156. package/libusb/msvc/libusb_static_2013.vcxproj +5 -9
  157. package/libusb/msvc/libusb_static_2013.vcxproj.filters +80 -0
  158. package/libusb/msvc/libusb_static_2015.vcxproj +5 -8
  159. package/libusb/msvc/libusb_static_2015.vcxproj.filters +80 -0
  160. package/libusb/msvc/libusb_static_2017.vcxproj +5 -8
  161. package/libusb/msvc/libusb_static_2017.vcxproj.filters +80 -0
  162. package/libusb/msvc/{libusb_static_2010.vcxproj → libusb_static_2019.vcxproj} +26 -9
  163. package/libusb/msvc/libusb_static_2019.vcxproj.filters +80 -0
  164. package/libusb/msvc/listdevs_2013.vcxproj +6 -3
  165. package/libusb/msvc/listdevs_2013.vcxproj.filters +23 -0
  166. package/libusb/msvc/listdevs_2015.vcxproj +6 -3
  167. package/libusb/msvc/listdevs_2015.vcxproj.filters +23 -0
  168. package/libusb/msvc/listdevs_2017.vcxproj +6 -7
  169. package/libusb/msvc/listdevs_2017.vcxproj.filters +23 -0
  170. package/libusb/msvc/listdevs_2019.vcxproj +105 -0
  171. package/libusb/msvc/listdevs_2019.vcxproj.filters +23 -0
  172. package/libusb/msvc/{listdevs_2010.vcxproj → sam3u_benchmark_2013.vcxproj} +13 -8
  173. package/libusb/msvc/sam3u_benchmark_2013.vcxproj.filters +26 -0
  174. package/libusb/msvc/{listdevs_2012.vcxproj → sam3u_benchmark_2015.vcxproj} +13 -9
  175. package/libusb/msvc/sam3u_benchmark_2015.vcxproj.filters +26 -0
  176. package/libusb/msvc/sam3u_benchmark_2017.vcxproj +106 -0
  177. package/libusb/msvc/sam3u_benchmark_2017.vcxproj.filters +26 -0
  178. package/libusb/msvc/sam3u_benchmark_2019.vcxproj +106 -0
  179. package/libusb/msvc/sam3u_benchmark_2019.vcxproj.filters +26 -0
  180. package/libusb/msvc/stress_2013.vcxproj +4 -2
  181. package/libusb/msvc/stress_2013.vcxproj.filters +32 -0
  182. package/libusb/msvc/stress_2015.vcxproj +4 -2
  183. package/libusb/msvc/stress_2015.vcxproj.filters +32 -0
  184. package/libusb/msvc/stress_2017.vcxproj +4 -6
  185. package/libusb/msvc/stress_2017.vcxproj.filters +32 -0
  186. package/libusb/msvc/{stress_2010.vcxproj → stress_2019.vcxproj} +26 -4
  187. package/libusb/msvc/stress_2019.vcxproj.filters +32 -0
  188. package/libusb/msvc/testlibusb_2013.vcxproj +6 -3
  189. package/libusb/msvc/testlibusb_2013.vcxproj.filters +23 -0
  190. package/libusb/msvc/testlibusb_2015.vcxproj +6 -3
  191. package/libusb/msvc/testlibusb_2015.vcxproj.filters +23 -0
  192. package/libusb/msvc/testlibusb_2017.vcxproj +6 -7
  193. package/libusb/msvc/testlibusb_2017.vcxproj.filters +23 -0
  194. package/libusb/msvc/{testlibusb_2010.vcxproj → testlibusb_2019.vcxproj} +28 -5
  195. package/libusb/msvc/testlibusb_2019.vcxproj.filters +23 -0
  196. package/libusb/msvc/xusb_2013.vcxproj +6 -3
  197. package/libusb/msvc/xusb_2013.vcxproj.filters +23 -0
  198. package/libusb/msvc/xusb_2015.vcxproj +6 -3
  199. package/libusb/msvc/xusb_2015.vcxproj.filters +23 -0
  200. package/libusb/msvc/xusb_2017.vcxproj +6 -7
  201. package/libusb/msvc/xusb_2017.vcxproj.filters +23 -0
  202. package/libusb/msvc/{xusb_2010.vcxproj → xusb_2019.vcxproj} +28 -5
  203. package/libusb/msvc/xusb_2019.vcxproj.filters +23 -0
  204. package/libusb/tests/Makefile.am +13 -1
  205. package/libusb/tests/libusb_testlib.h +12 -43
  206. package/libusb/tests/stress.c +59 -50
  207. package/libusb/tests/testlib.c +78 -171
  208. package/libusb/tests/umockdev.c +1175 -0
  209. package/libusb.gypi +10 -11
  210. package/package.json +1 -1
  211. package/prebuilds/android-arm/node.napi.armv7.node +0 -0
  212. package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
  213. package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
  214. package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
  215. package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
  216. package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
  217. package/prebuilds/linux-ia32/node.napi.node +0 -0
  218. package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
  219. package/prebuilds/linux-x64/node.napi.musl.node +0 -0
  220. package/prebuilds/win32-ia32/node.napi.node +0 -0
  221. package/prebuilds/win32-x64/node.napi.node +0 -0
  222. package/src/device.cc +12 -7
  223. package/src/node_usb.cc +10 -0
  224. package/test/usb.coffee +6 -0
  225. package/tsc/index.ts +2 -0
  226. package/tsc/usb/bindings.ts +5 -0
  227. package/tsc/usb/device.ts +6 -0
  228. package/tsc/usb/index.ts +5 -8
  229. package/tsc/webusb/webusb-device.ts +67 -124
  230. package/dist/webusb/mutex.d.ts +0 -22
  231. package/dist/webusb/mutex.js +0 -89
  232. package/dist/webusb/mutex.js.map +0 -1
  233. package/libusb/.private/bd.cmd +0 -89
  234. package/libusb/.private/bwince.cmd +0 -57
  235. package/libusb/.private/wbs_wince.txt +0 -42
  236. package/libusb/Brewfile +0 -4
  237. package/libusb/appveyor_cygwin.bat +0 -11
  238. package/libusb/appveyor_minGW.bat +0 -19
  239. package/libusb/doc/Makefile.am +0 -9
  240. package/libusb/examples/dpfp_threaded.c +0 -557
  241. package/libusb/libusb/hotplug.h +0 -99
  242. package/libusb/libusb/os/poll_posix.c +0 -84
  243. package/libusb/libusb/os/poll_posix.h +0 -14
  244. package/libusb/libusb/os/poll_windows.c +0 -447
  245. package/libusb/libusb/os/poll_windows.h +0 -98
  246. package/libusb/libusb/os/wince_usb.c +0 -888
  247. package/libusb/libusb/os/wince_usb.h +0 -126
  248. package/libusb/libusb/os/windows_nt_common.c +0 -1010
  249. package/libusb/libusb/os/windows_nt_common.h +0 -110
  250. package/libusb/libusb/os/windows_nt_shared_types.h +0 -147
  251. package/libusb/msvc/appveyor.bat +0 -27
  252. package/libusb/msvc/ddk_build.cmd +0 -219
  253. package/libusb/msvc/errno.h +0 -102
  254. package/libusb/msvc/fxload_sources +0 -23
  255. package/libusb/msvc/getopt_2005.vcproj +0 -288
  256. package/libusb/msvc/getopt_2012.vcxproj +0 -73
  257. package/libusb/msvc/getopt_sources +0 -24
  258. package/libusb/msvc/hotplugtest_sources +0 -20
  259. package/libusb/msvc/inttypes.h +0 -295
  260. package/libusb/msvc/libusb.dsw +0 -71
  261. package/libusb/msvc/libusb_2005.sln +0 -95
  262. package/libusb/msvc/libusb_2010.sln +0 -105
  263. package/libusb/msvc/libusb_2012.sln +0 -105
  264. package/libusb/msvc/libusb_dll.dsp +0 -194
  265. package/libusb/msvc/libusb_dll_2005.vcproj +0 -464
  266. package/libusb/msvc/libusb_dll_2012.vcxproj +0 -107
  267. package/libusb/msvc/libusb_dll_wince.vcproj +0 -1251
  268. package/libusb/msvc/libusb_sources +0 -43
  269. package/libusb/msvc/libusb_static.dsp +0 -174
  270. package/libusb/msvc/libusb_static_2005.vcproj +0 -390
  271. package/libusb/msvc/libusb_static_2012.vcxproj +0 -98
  272. package/libusb/msvc/libusb_static_wince.vcproj +0 -1179
  273. package/libusb/msvc/libusb_wince.sln +0 -246
  274. package/libusb/msvc/listdevs.dsp +0 -103
  275. package/libusb/msvc/listdevs_2005.vcproj +0 -360
  276. package/libusb/msvc/listdevs_sources +0 -20
  277. package/libusb/msvc/listdevs_wince.vcproj +0 -1120
  278. package/libusb/msvc/missing.c +0 -80
  279. package/libusb/msvc/stdint.h +0 -256
  280. package/libusb/msvc/stress_2005.vcproj +0 -390
  281. package/libusb/msvc/stress_2012.vcxproj +0 -87
  282. package/libusb/msvc/stress_sources +0 -21
  283. package/libusb/msvc/stress_wince.vcproj +0 -1128
  284. package/libusb/msvc/testlibusb_2012.vcxproj +0 -83
  285. package/libusb/msvc/testlibusb_sources +0 -20
  286. package/libusb/msvc/xusb.dsp +0 -102
  287. package/libusb/msvc/xusb_2005.vcproj +0 -344
  288. package/libusb/msvc/xusb_2012.vcxproj +0 -83
  289. package/libusb/msvc/xusb_sources +0 -20
  290. package/libusb/msvc/xusb_wince.vcproj +0 -1120
  291. package/libusb/travis-autogen.sh +0 -39
  292. package/tsc/webusb/mutex.ts +0 -38
@@ -21,24 +21,7 @@
21
21
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
22
  */
23
23
 
24
- #include <config.h>
25
-
26
- #include <assert.h>
27
- #include <errno.h>
28
- #include <stdint.h>
29
- #include <stdlib.h>
30
- #include <string.h>
31
- #include <time.h>
32
- #ifdef HAVE_SYS_TIME_H
33
- #include <sys/time.h>
34
- #endif
35
- #ifdef USBI_TIMERFD_AVAILABLE
36
- #include <unistd.h>
37
- #include <sys/timerfd.h>
38
- #endif
39
-
40
24
  #include "libusbi.h"
41
- #include "hotplug.h"
42
25
 
43
26
  /**
44
27
  * \page libusb_io Synchronous and asynchronous device I/O
@@ -89,7 +72,7 @@
89
72
  * a single function call. When the function call returns, the transfer has
90
73
  * completed and you can parse the results.
91
74
  *
92
- * If you have used the libusb-0.1 before, this I/O style will seem familar to
75
+ * If you have used libusb-0.1 before, this I/O style will seem familiar to
93
76
  * you. libusb-0.1 only offered a synchronous interface.
94
77
  *
95
78
  * In our input device example, to read button presses you might write code
@@ -115,7 +98,7 @@ if (r == 0 && actual_length == sizeof(data)) {
115
98
  * sleeping for that long. Execution will be tied up inside the library -
116
99
  * the entire thread will be useless for that duration.
117
100
  *
118
- * Another issue is that by tieing up the thread with that single transaction
101
+ * Another issue is that by tying up the thread with that single transaction
119
102
  * there is no possibility of performing I/O with multiple endpoints and/or
120
103
  * multiple devices simultaneously, unless you resort to creating one thread
121
104
  * per transaction.
@@ -333,9 +316,40 @@ if (r == 0 && actual_length == sizeof(data)) {
333
316
  * Freeing the transfer after it has been cancelled but before cancellation
334
317
  * has completed will result in undefined behaviour.
335
318
  *
319
+ * \attention
336
320
  * When a transfer is cancelled, some of the data may have been transferred.
337
- * libusb will communicate this to you in the transfer callback. Do not assume
338
- * that no data was transferred.
321
+ * libusb will communicate this to you in the transfer callback.
322
+ * <b>Do not assume that no data was transferred.</b>
323
+ *
324
+ * \section asyncpartial Partial data transfer resulting from cancellation
325
+ *
326
+ * As noted above, some of the data may have been transferred at the time a
327
+ * transfer is cancelled. It is helpful to see how this is possible if you
328
+ * consider a bulk transfer to an endpoint with a packet size of 64 bytes.
329
+ * Supposing you submit a 512-byte transfer to this endpoint, the operating
330
+ * system will divide this transfer up into 8 separate 64-byte frames that the
331
+ * host controller will schedule for the device to transfer data. If this
332
+ * transfer is cancelled while the device is transferring data, a subset of
333
+ * these frames may be descheduled from the host controller before the device
334
+ * has the opportunity to finish transferring data to the host.
335
+ *
336
+ * What your application should do with a partial data transfer is a policy
337
+ * decision; there is no single answer that satisfies the needs of every
338
+ * application. The data that was successfully transferred should be
339
+ * considered entirely valid, but your application must decide what to do with
340
+ * the remaining data that was not transferred. Some possible actions to take
341
+ * are:
342
+ * - Resubmit another transfer for the remaining data, possibly with a shorter
343
+ * timeout
344
+ * - Discard the partially transferred data and report an error
345
+ *
346
+ * \section asynctimeout Timeouts
347
+ *
348
+ * When a transfer times out, libusb internally notes this and attempts to
349
+ * cancel the transfer. As noted in \ref asyncpartial "above", it is possible
350
+ * that some of the data may actually have been transferred. Your application
351
+ * should <b>always</b> check how much data was actually transferred once the
352
+ * transfer completes and act accordingly.
339
353
  *
340
354
  * \section bulk_overflows Overflows on device-to-host bulk/interrupt endpoints
341
355
  *
@@ -393,7 +407,7 @@ if (r == 0 && actual_length == sizeof(data)) {
393
407
  * wLength of the setup packet, rather than the size of the data buffer. So,
394
408
  * if your wLength was 4, your transfer's <tt>length</tt> was 12, then you
395
409
  * should expect an <tt>actual_length</tt> of 4 to indicate that the data was
396
- * transferred in entirity.
410
+ * transferred in entirety.
397
411
  *
398
412
  * To simplify parsing of setup packets and obtaining the data from the
399
413
  * correct offset, you may wish to use the libusb_control_transfer_get_data()
@@ -472,14 +486,21 @@ if (r == 0 && actual_length == sizeof(data)) {
472
486
  * libusb_get_iso_packet_buffer() and libusb_get_iso_packet_buffer_simple()
473
487
  * functions may help you here.
474
488
  *
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,
489
+ * \section asynclimits Transfer length limitations
490
+ *
491
+ * Some operating systems may impose limits on the length of the transfer data
492
+ * buffer or, in the case of isochronous transfers, the length of individual
493
+ * isochronous packets. Such limits can be difficult for libusb to detect, so
494
+ * in most cases the library will simply try and submit the transfer as set up
495
+ * by you. If the transfer fails to submit because it is too large,
480
496
  * libusb_submit_transfer() will return
481
497
  * \ref libusb_error::LIBUSB_ERROR_INVALID_PARAM "LIBUSB_ERROR_INVALID_PARAM".
482
498
  *
499
+ * The following are known limits for control transfer lengths. Note that this
500
+ * length includes the 8-byte setup packet.
501
+ * - Linux (4,096 bytes)
502
+ * - Windows (4,096 bytes)
503
+ *
483
504
  * \section asyncmem Memory caveats
484
505
  *
485
506
  * In most circumstances, it is not safe to use stack memory for transfer
@@ -520,7 +541,14 @@ if (r == 0 && actual_length == sizeof(data)) {
520
541
  * application must call into when libusb has work do to. This gives libusb
521
542
  * the opportunity to reap pending transfers, invoke callbacks, etc.
522
543
  *
523
- * There are 2 different approaches to dealing with libusb_handle_events:
544
+ * \note
545
+ * All event handling is performed by whichever thread calls the
546
+ * libusb_handle_events() function. libusb does not invoke any callbacks
547
+ * outside of this context. Consequently, any callbacks will be run on the
548
+ * thread that calls the libusb_handle_events() function.
549
+ *
550
+ * When to call the libusb_handle_events() function depends on which model
551
+ * your application decides to use. The 2 different approaches:
524
552
  *
525
553
  * -# Repeatedly call libusb_handle_events() in blocking mode from a dedicated
526
554
  * thread.
@@ -541,7 +569,7 @@ if (r == 0 && actual_length == sizeof(data)) {
541
569
  *
542
570
  * Lets begin with stating the obvious: If you're going to use a separate
543
571
  * thread for libusb event handling, your callback functions MUST be
544
- * threadsafe.
572
+ * thread-safe.
545
573
  *
546
574
  * Other then that doing event handling from a separate thread, is mostly
547
575
  * simple. You can use an event thread function as follows:
@@ -781,7 +809,7 @@ while (user has not requested application exit) {
781
809
  * system calls. This is directly exposed at the
782
810
  * \ref libusb_asyncio "asynchronous interface" but it is important to note that the
783
811
  * \ref libusb_syncio "synchronous interface" is implemented on top of the
784
- * asynchonrous interface, therefore the same considerations apply.
812
+ * asynchronous interface, therefore the same considerations apply.
785
813
  *
786
814
  * The issue is that if two or more threads are concurrently calling poll()
787
815
  * or select() on libusb's file descriptors then only one of those threads
@@ -889,6 +917,11 @@ void myfunc() {
889
917
  * do is submit a single transfer and wait for its completion, then using
890
918
  * one of the synchronous I/O functions is much easier.
891
919
  *
920
+ * \note
921
+ * The `completed` variable must be modified while holding the event lock,
922
+ * otherwise a race condition can still exist. It is simplest to do so from
923
+ * within the transfer callback as shown above.
924
+ *
892
925
  * \section eventlock The events lock
893
926
  *
894
927
  * The problem is when we consider the fact that libusb exposes file
@@ -986,7 +1019,7 @@ printf("completed!\n");
986
1019
  * event handling), because the event waiter seems to have taken the event
987
1020
  * waiters lock while waiting for an event. However, the system does support
988
1021
  * multiple event waiters, because libusb_wait_for_event() actually drops
989
- * the lock while waiting, and reaquires it before continuing.
1022
+ * the lock while waiting, and reacquires it before continuing.
990
1023
  *
991
1024
  * We have now implemented code which can dynamically handle situations where
992
1025
  * nobody is handling events (so we should do it ourselves), and it can also
@@ -1131,46 +1164,40 @@ int usbi_io_init(struct libusb_context *ctx)
1131
1164
  usbi_mutex_init(&ctx->event_data_lock);
1132
1165
  usbi_tls_key_create(&ctx->event_handling_key);
1133
1166
  list_init(&ctx->flying_transfers);
1134
- list_init(&ctx->ipollfds);
1135
- list_init(&ctx->removed_ipollfds);
1167
+ list_init(&ctx->event_sources);
1168
+ list_init(&ctx->removed_event_sources);
1136
1169
  list_init(&ctx->hotplug_msgs);
1137
1170
  list_init(&ctx->completed_transfers);
1138
1171
 
1139
- /* FIXME should use an eventfd on kernels that support it */
1140
- r = usbi_pipe(ctx->event_pipe);
1141
- if (r < 0) {
1142
- r = LIBUSB_ERROR_OTHER;
1172
+ r = usbi_create_event(&ctx->event);
1173
+ if (r < 0)
1143
1174
  goto err;
1144
- }
1145
1175
 
1146
- r = usbi_add_pollfd(ctx, ctx->event_pipe[0], POLLIN);
1176
+ r = usbi_add_event_source(ctx, USBI_EVENT_OS_HANDLE(&ctx->event), USBI_EVENT_POLL_EVENTS);
1147
1177
  if (r < 0)
1148
- goto err_close_pipe;
1149
-
1150
- #ifdef USBI_TIMERFD_AVAILABLE
1151
- ctx->timerfd = timerfd_create(usbi_backend.get_timerfd_clockid(),
1152
- TFD_NONBLOCK | TFD_CLOEXEC);
1153
- if (ctx->timerfd >= 0) {
1154
- usbi_dbg("using timerfd for timeouts");
1155
- r = usbi_add_pollfd(ctx, ctx->timerfd, POLLIN);
1178
+ goto err_destroy_event;
1179
+
1180
+ #ifdef HAVE_OS_TIMER
1181
+ r = usbi_create_timer(&ctx->timer);
1182
+ if (r == 0) {
1183
+ usbi_dbg(ctx, "using timer for timeouts");
1184
+ r = usbi_add_event_source(ctx, USBI_TIMER_OS_HANDLE(&ctx->timer), USBI_TIMER_POLL_EVENTS);
1156
1185
  if (r < 0)
1157
- goto err_close_timerfd;
1186
+ goto err_destroy_timer;
1158
1187
  } else {
1159
- usbi_dbg("timerfd not available (code %d error %d)", ctx->timerfd, errno);
1160
- ctx->timerfd = -1;
1188
+ usbi_dbg(ctx, "timer not available for timeouts");
1161
1189
  }
1162
1190
  #endif
1163
1191
 
1164
1192
  return 0;
1165
1193
 
1166
- #ifdef USBI_TIMERFD_AVAILABLE
1167
- err_close_timerfd:
1168
- close(ctx->timerfd);
1169
- usbi_remove_pollfd(ctx, ctx->event_pipe[0]);
1194
+ #ifdef HAVE_OS_TIMER
1195
+ err_destroy_timer:
1196
+ usbi_destroy_timer(&ctx->timer);
1197
+ usbi_remove_event_source(ctx, USBI_EVENT_OS_HANDLE(&ctx->event));
1170
1198
  #endif
1171
- err_close_pipe:
1172
- usbi_close(ctx->event_pipe[0]);
1173
- usbi_close(ctx->event_pipe[1]);
1199
+ err_destroy_event:
1200
+ usbi_destroy_event(&ctx->event);
1174
1201
  err:
1175
1202
  usbi_mutex_destroy(&ctx->flying_transfers_lock);
1176
1203
  usbi_mutex_destroy(&ctx->events_lock);
@@ -1181,65 +1208,54 @@ err:
1181
1208
  return r;
1182
1209
  }
1183
1210
 
1184
- static void cleanup_removed_pollfds(struct libusb_context *ctx)
1211
+ static void cleanup_removed_event_sources(struct libusb_context *ctx)
1185
1212
  {
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);
1213
+ struct usbi_event_source *ievent_source, *tmp;
1214
+
1215
+ for_each_removed_event_source_safe(ctx, ievent_source, tmp) {
1216
+ list_del(&ievent_source->list);
1217
+ free(ievent_source);
1190
1218
  }
1191
1219
  }
1192
1220
 
1193
1221
  void usbi_io_exit(struct libusb_context *ctx)
1194
1222
  {
1195
- usbi_remove_pollfd(ctx, ctx->event_pipe[0]);
1196
- usbi_close(ctx->event_pipe[0]);
1197
- usbi_close(ctx->event_pipe[1]);
1198
- #ifdef USBI_TIMERFD_AVAILABLE
1199
- if (usbi_using_timerfd(ctx)) {
1200
- usbi_remove_pollfd(ctx, ctx->timerfd);
1201
- close(ctx->timerfd);
1223
+ #ifdef HAVE_OS_TIMER
1224
+ if (usbi_using_timer(ctx)) {
1225
+ usbi_remove_event_source(ctx, USBI_TIMER_OS_HANDLE(&ctx->timer));
1226
+ usbi_destroy_timer(&ctx->timer);
1202
1227
  }
1203
1228
  #endif
1229
+ usbi_remove_event_source(ctx, USBI_EVENT_OS_HANDLE(&ctx->event));
1230
+ usbi_destroy_event(&ctx->event);
1204
1231
  usbi_mutex_destroy(&ctx->flying_transfers_lock);
1205
1232
  usbi_mutex_destroy(&ctx->events_lock);
1206
1233
  usbi_mutex_destroy(&ctx->event_waiters_lock);
1207
1234
  usbi_cond_destroy(&ctx->event_waiters_cond);
1208
1235
  usbi_mutex_destroy(&ctx->event_data_lock);
1209
1236
  usbi_tls_key_delete(ctx->event_handling_key);
1210
- free(ctx->pollfds);
1211
- cleanup_removed_pollfds(ctx);
1237
+ cleanup_removed_event_sources(ctx);
1238
+ free(ctx->event_data);
1212
1239
  }
1213
1240
 
1214
- static int calculate_timeout(struct usbi_transfer *transfer)
1241
+ static void calculate_timeout(struct usbi_transfer *itransfer)
1215
1242
  {
1216
- int r;
1217
- struct timespec current_time;
1218
1243
  unsigned int timeout =
1219
- USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout;
1244
+ USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer)->timeout;
1220
1245
 
1221
1246
  if (!timeout) {
1222
- timerclear(&transfer->timeout);
1223
- return 0;
1224
- }
1225
-
1226
- r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, &current_time);
1227
- if (r < 0) {
1228
- usbi_err(ITRANSFER_CTX(transfer),
1229
- "failed to read monotonic clock, errno=%d", errno);
1230
- return r;
1247
+ TIMESPEC_CLEAR(&itransfer->timeout);
1248
+ return;
1231
1249
  }
1232
1250
 
1233
- current_time.tv_sec += timeout / 1000;
1234
- current_time.tv_nsec += (timeout % 1000) * 1000000;
1251
+ usbi_get_monotonic_time(&itransfer->timeout);
1235
1252
 
1236
- while (current_time.tv_nsec >= 1000000000) {
1237
- current_time.tv_nsec -= 1000000000;
1238
- current_time.tv_sec++;
1253
+ itransfer->timeout.tv_sec += timeout / 1000U;
1254
+ itransfer->timeout.tv_nsec += (timeout % 1000U) * 1000000L;
1255
+ if (itransfer->timeout.tv_nsec >= NSEC_PER_SEC) {
1256
+ ++itransfer->timeout.tv_sec;
1257
+ itransfer->timeout.tv_nsec -= NSEC_PER_SEC;
1239
1258
  }
1240
-
1241
- TIMESPEC_TO_TIMEVAL(&transfer->timeout, &current_time);
1242
- return 0;
1243
1259
  }
1244
1260
 
1245
1261
  /** \ingroup libusb_asyncio
@@ -1269,26 +1285,30 @@ DEFAULT_VISIBILITY
1269
1285
  struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(
1270
1286
  int iso_packets)
1271
1287
  {
1272
- struct libusb_transfer *transfer;
1273
- size_t os_alloc_size;
1288
+ size_t priv_size;
1274
1289
  size_t alloc_size;
1290
+ unsigned char *ptr;
1275
1291
  struct usbi_transfer *itransfer;
1292
+ struct libusb_transfer *transfer;
1276
1293
 
1277
1294
  assert(iso_packets >= 0);
1295
+ if (iso_packets < 0)
1296
+ return NULL;
1278
1297
 
1279
- os_alloc_size = usbi_backend.transfer_priv_size;
1280
- alloc_size = sizeof(struct usbi_transfer)
1298
+ priv_size = PTR_ALIGN(usbi_backend.transfer_priv_size);
1299
+ alloc_size = priv_size
1300
+ + sizeof(struct usbi_transfer)
1281
1301
  + sizeof(struct libusb_transfer)
1282
- + (sizeof(struct libusb_iso_packet_descriptor) * (size_t)iso_packets)
1283
- + os_alloc_size;
1284
- itransfer = calloc(1, alloc_size);
1285
- if (!itransfer)
1302
+ + (sizeof(struct libusb_iso_packet_descriptor) * (size_t)iso_packets);
1303
+ ptr = calloc(1, alloc_size);
1304
+ if (!ptr)
1286
1305
  return NULL;
1287
1306
 
1307
+ itransfer = (struct usbi_transfer *)(ptr + priv_size);
1288
1308
  itransfer->num_iso_packets = iso_packets;
1309
+ itransfer->priv = ptr;
1289
1310
  usbi_mutex_init(&itransfer->lock);
1290
1311
  transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1291
- usbi_dbg("transfer %p", transfer);
1292
1312
  return transfer;
1293
1313
  }
1294
1314
 
@@ -1312,67 +1332,60 @@ struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(
1312
1332
  void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer)
1313
1333
  {
1314
1334
  struct usbi_transfer *itransfer;
1335
+ size_t priv_size;
1336
+ unsigned char *ptr;
1337
+
1315
1338
  if (!transfer)
1316
1339
  return;
1317
1340
 
1318
- usbi_dbg("transfer %p", transfer);
1341
+ usbi_dbg(TRANSFER_CTX(transfer), "transfer %p", transfer);
1319
1342
  if (transfer->flags & LIBUSB_TRANSFER_FREE_BUFFER)
1320
1343
  free(transfer->buffer);
1321
1344
 
1322
1345
  itransfer = LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
1323
1346
  usbi_mutex_destroy(&itransfer->lock);
1324
- free(itransfer);
1325
- }
1326
-
1327
- #ifdef USBI_TIMERFD_AVAILABLE
1328
- static int disarm_timerfd(struct libusb_context *ctx)
1329
- {
1330
- const struct itimerspec disarm_timer = { { 0, 0 }, { 0, 0 } };
1331
- int r;
1347
+ if (itransfer->dev)
1348
+ libusb_unref_device(itransfer->dev);
1332
1349
 
1333
- usbi_dbg("");
1334
- r = timerfd_settime(ctx->timerfd, 0, &disarm_timer, NULL);
1335
- if (r < 0)
1336
- return LIBUSB_ERROR_OTHER;
1337
- else
1338
- return 0;
1350
+ priv_size = PTR_ALIGN(usbi_backend.transfer_priv_size);
1351
+ ptr = (unsigned char *)itransfer - priv_size;
1352
+ assert(ptr == itransfer->priv);
1353
+ free(ptr);
1339
1354
  }
1340
1355
 
1341
- /* iterates through the flying transfers, and rearms the timerfd based on the
1356
+ /* iterates through the flying transfers, and rearms the timer based on the
1342
1357
  * next upcoming timeout.
1343
1358
  * must be called with flying_list locked.
1344
1359
  * returns 0 on success or a LIBUSB_ERROR code on failure.
1345
1360
  */
1346
- static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
1361
+ #ifdef HAVE_OS_TIMER
1362
+ static int arm_timer_for_next_timeout(struct libusb_context *ctx)
1347
1363
  {
1348
- struct usbi_transfer *transfer;
1364
+ struct usbi_transfer *itransfer;
1349
1365
 
1350
- list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
1351
- struct timeval *cur_tv = &transfer->timeout;
1366
+ if (!usbi_using_timer(ctx))
1367
+ return 0;
1368
+
1369
+ for_each_transfer(ctx, itransfer) {
1370
+ struct timespec *cur_ts = &itransfer->timeout;
1352
1371
 
1353
1372
  /* if we've reached transfers of infinite timeout, then we have no
1354
1373
  * arming to do */
1355
- if (!timerisset(cur_tv))
1356
- goto disarm;
1374
+ if (!TIMESPEC_IS_SET(cur_ts))
1375
+ break;
1357
1376
 
1358
1377
  /* act on first transfer that has not already been handled */
1359
- if (!(transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))) {
1360
- int r;
1361
- const struct itimerspec it = { {0, 0},
1362
- { cur_tv->tv_sec, cur_tv->tv_usec * 1000 } };
1363
- usbi_dbg("next timeout originally %dms", USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout);
1364
- r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL);
1365
- if (r < 0)
1366
- return LIBUSB_ERROR_OTHER;
1367
- return 0;
1378
+ if (!(itransfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))) {
1379
+ usbi_dbg(ctx, "next timeout originally %ums", USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer)->timeout);
1380
+ return usbi_arm_timer(&ctx->timer, cur_ts);
1368
1381
  }
1369
1382
  }
1370
1383
 
1371
- disarm:
1372
- return disarm_timerfd(ctx);
1384
+ usbi_dbg(ctx, "no timeouts, disarming timer");
1385
+ return usbi_disarm_timer(&ctx->timer);
1373
1386
  }
1374
1387
  #else
1375
- static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
1388
+ static inline int arm_timer_for_next_timeout(struct libusb_context *ctx)
1376
1389
  {
1377
1390
  UNUSED(ctx);
1378
1391
  return 0;
@@ -1382,40 +1395,36 @@ static int arm_timerfd_for_next_timeout(struct libusb_context *ctx)
1382
1395
  /* add a transfer to the (timeout-sorted) active transfers list.
1383
1396
  * This function will return non 0 if fails to update the timer,
1384
1397
  * in which case the transfer is *not* on the flying_transfers list. */
1385
- static int add_to_flying_list(struct usbi_transfer *transfer)
1398
+ static int add_to_flying_list(struct usbi_transfer *itransfer)
1386
1399
  {
1387
1400
  struct usbi_transfer *cur;
1388
- struct timeval *timeout = &transfer->timeout;
1389
- struct libusb_context *ctx = ITRANSFER_CTX(transfer);
1390
- int r;
1401
+ struct timespec *timeout = &itransfer->timeout;
1402
+ struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
1403
+ int r = 0;
1391
1404
  int first = 1;
1392
1405
 
1393
- r = calculate_timeout(transfer);
1394
- if (r)
1395
- return r;
1406
+ calculate_timeout(itransfer);
1396
1407
 
1397
1408
  /* if we have no other flying transfers, start the list with this one */
1398
1409
  if (list_empty(&ctx->flying_transfers)) {
1399
- list_add(&transfer->list, &ctx->flying_transfers);
1410
+ list_add(&itransfer->list, &ctx->flying_transfers);
1400
1411
  goto out;
1401
1412
  }
1402
1413
 
1403
1414
  /* if we have infinite timeout, append to end of list */
1404
- if (!timerisset(timeout)) {
1405
- list_add_tail(&transfer->list, &ctx->flying_transfers);
1415
+ if (!TIMESPEC_IS_SET(timeout)) {
1416
+ list_add_tail(&itransfer->list, &ctx->flying_transfers);
1406
1417
  /* first is irrelevant in this case */
1407
1418
  goto out;
1408
1419
  }
1409
1420
 
1410
1421
  /* otherwise, find appropriate place in list */
1411
- list_for_each_entry(cur, &ctx->flying_transfers, list, struct usbi_transfer) {
1422
+ for_each_transfer(ctx, cur) {
1412
1423
  /* find first timeout that occurs after the transfer in question */
1413
- struct timeval *cur_tv = &cur->timeout;
1424
+ struct timespec *cur_ts = &cur->timeout;
1414
1425
 
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);
1426
+ if (!TIMESPEC_IS_SET(cur_ts) || TIMESPEC_CMP(cur_ts, timeout, >)) {
1427
+ list_add_tail(&itransfer->list, &cur->list);
1419
1428
  goto out;
1420
1429
  }
1421
1430
  first = 0;
@@ -1423,28 +1432,22 @@ static int add_to_flying_list(struct usbi_transfer *transfer)
1423
1432
  /* first is 0 at this stage (list not empty) */
1424
1433
 
1425
1434
  /* otherwise we need to be inserted at the end */
1426
- list_add_tail(&transfer->list, &ctx->flying_transfers);
1435
+ list_add_tail(&itransfer->list, &ctx->flying_transfers);
1427
1436
  out:
1428
- #ifdef USBI_TIMERFD_AVAILABLE
1429
- if (first && usbi_using_timerfd(ctx) && timerisset(timeout)) {
1437
+ #ifdef HAVE_OS_TIMER
1438
+ if (first && usbi_using_timer(ctx) && TIMESPEC_IS_SET(timeout)) {
1430
1439
  /* 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
- }
1440
+ * rearm the timer with this transfer's timeout */
1441
+ usbi_dbg(ctx, "arm timer for timeout in %ums (first in line)",
1442
+ USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer)->timeout);
1443
+ r = usbi_arm_timer(&ctx->timer, timeout);
1441
1444
  }
1442
1445
  #else
1443
1446
  UNUSED(first);
1444
1447
  #endif
1445
1448
 
1446
1449
  if (r)
1447
- list_del(&transfer->list);
1450
+ list_del(&itransfer->list);
1448
1451
 
1449
1452
  return r;
1450
1453
  }
@@ -1453,18 +1456,18 @@ out:
1453
1456
  * This function will *always* remove the transfer from the
1454
1457
  * flying_transfers list. It will return a LIBUSB_ERROR code
1455
1458
  * if it fails to update the timer for the next timeout. */
1456
- static int remove_from_flying_list(struct usbi_transfer *transfer)
1459
+ static int remove_from_flying_list(struct usbi_transfer *itransfer)
1457
1460
  {
1458
- struct libusb_context *ctx = ITRANSFER_CTX(transfer);
1459
- int rearm_timerfd;
1461
+ struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
1462
+ int rearm_timer;
1460
1463
  int r = 0;
1461
1464
 
1462
1465
  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);
1466
+ rearm_timer = (TIMESPEC_IS_SET(&itransfer->timeout) &&
1467
+ list_first_entry(&ctx->flying_transfers, struct usbi_transfer, list) == itransfer);
1468
+ list_del(&itransfer->list);
1469
+ if (rearm_timer)
1470
+ r = arm_timer_for_next_timeout(ctx);
1468
1471
  usbi_mutex_unlock(&ctx->flying_transfers_lock);
1469
1472
 
1470
1473
  return r;
@@ -1481,17 +1484,23 @@ static int remove_from_flying_list(struct usbi_transfer *transfer)
1481
1484
  * \returns LIBUSB_ERROR_NOT_SUPPORTED if the transfer flags are not supported
1482
1485
  * by the operating system.
1483
1486
  * \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than
1484
- * the operating system and/or hardware can support
1487
+ * the operating system and/or hardware can support (see \ref asynclimits)
1485
1488
  * \returns another LIBUSB_ERROR code on other failure
1486
1489
  */
1487
1490
  int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
1488
1491
  {
1489
1492
  struct usbi_transfer *itransfer =
1490
1493
  LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
1491
- struct libusb_context *ctx = TRANSFER_CTX(transfer);
1494
+ struct libusb_context *ctx;
1492
1495
  int r;
1493
1496
 
1494
- usbi_dbg("transfer %p", transfer);
1497
+ assert(transfer->dev_handle);
1498
+ if (itransfer->dev)
1499
+ libusb_unref_device(itransfer->dev);
1500
+ itransfer->dev = libusb_ref_device(transfer->dev_handle->dev);
1501
+
1502
+ ctx = HANDLE_CTX(transfer->dev_handle);
1503
+ usbi_dbg(ctx, "transfer %p", transfer);
1495
1504
 
1496
1505
  /*
1497
1506
  * Important note on locking, this function takes / releases locks
@@ -1543,15 +1552,13 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
1543
1552
  }
1544
1553
  /*
1545
1554
  * We must release the flying transfers lock here, because with
1546
- * some backends the submit_transfer method is synchroneous.
1555
+ * some backends the submit_transfer method is synchronous.
1547
1556
  */
1548
1557
  usbi_mutex_unlock(&ctx->flying_transfers_lock);
1549
1558
 
1550
1559
  r = usbi_backend.submit_transfer(itransfer);
1551
1560
  if (r == LIBUSB_SUCCESS) {
1552
1561
  itransfer->state_flags |= USBI_TRANSFER_IN_FLIGHT;
1553
- /* keep a reference to this device */
1554
- libusb_ref_device(transfer->dev_handle->dev);
1555
1562
  }
1556
1563
  usbi_mutex_unlock(&itransfer->lock);
1557
1564
 
@@ -1569,6 +1576,26 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
1569
1576
  * \ref libusb_transfer_status::LIBUSB_TRANSFER_CANCELLED
1570
1577
  * "LIBUSB_TRANSFER_CANCELLED."
1571
1578
  *
1579
+ * This function behaves differently on Darwin-based systems (macOS and iOS):
1580
+ *
1581
+ * - Calling this function for one transfer will cause all transfers on the
1582
+ * same endpoint to be cancelled. Your callback function will be invoked with
1583
+ * a transfer status of
1584
+ * \ref libusb_transfer_status::LIBUSB_TRANSFER_CANCELLED
1585
+ * "LIBUSB_TRANSFER_CANCELLED" for each transfer that was cancelled.
1586
+
1587
+ * - Calling this function also sends a \c ClearFeature(ENDPOINT_HALT) request
1588
+ * for the transfer's endpoint. If the device does not handle this request
1589
+ * correctly, the data toggle bits for the endpoint can be left out of sync
1590
+ * between host and device, which can have unpredictable results when the
1591
+ * next data is sent on the endpoint, including data being silently lost.
1592
+ * A call to \ref libusb_clear_halt will not resolve this situation, since
1593
+ * that function uses the same request. Therefore, if your program runs on
1594
+ * Darwin and uses a device that does not correctly implement
1595
+ * \c ClearFeature(ENDPOINT_HALT) requests, it may only be safe to cancel
1596
+ * transfers when followed by a device reset using
1597
+ * \ref libusb_reset_device.
1598
+ *
1572
1599
  * \param transfer the transfer to cancel
1573
1600
  * \returns 0 on success
1574
1601
  * \returns LIBUSB_ERROR_NOT_FOUND if the transfer is not in progress,
@@ -1579,9 +1606,10 @@ int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer)
1579
1606
  {
1580
1607
  struct usbi_transfer *itransfer =
1581
1608
  LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
1609
+ struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
1582
1610
  int r;
1583
1611
 
1584
- usbi_dbg("transfer %p", transfer );
1612
+ usbi_dbg(ctx, "transfer %p", transfer );
1585
1613
  usbi_mutex_lock(&itransfer->lock);
1586
1614
  if (!(itransfer->state_flags & USBI_TRANSFER_IN_FLIGHT)
1587
1615
  || (itransfer->state_flags & USBI_TRANSFER_CANCELLING)) {
@@ -1592,10 +1620,9 @@ int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer)
1592
1620
  if (r < 0) {
1593
1621
  if (r != LIBUSB_ERROR_NOT_FOUND &&
1594
1622
  r != LIBUSB_ERROR_NO_DEVICE)
1595
- usbi_err(TRANSFER_CTX(transfer),
1596
- "cancel transfer failed error %d", r);
1623
+ usbi_err(ctx, "cancel transfer failed error %d", r);
1597
1624
  else
1598
- usbi_dbg("cancel transfer failed error %d", r);
1625
+ usbi_dbg(ctx, "cancel transfer failed error %d", r);
1599
1626
 
1600
1627
  if (r == LIBUSB_ERROR_NO_DEVICE)
1601
1628
  itransfer->state_flags |= USBI_TRANSFER_DEVICE_DISAPPEARED;
@@ -1658,13 +1685,13 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
1658
1685
  {
1659
1686
  struct libusb_transfer *transfer =
1660
1687
  USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
1661
- struct libusb_device_handle *dev_handle = transfer->dev_handle;
1688
+ struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
1662
1689
  uint8_t flags;
1663
1690
  int r;
1664
1691
 
1665
1692
  r = remove_from_flying_list(itransfer);
1666
1693
  if (r < 0)
1667
- usbi_err(ITRANSFER_CTX(itransfer), "failed to set timer for next timeout, errno=%d", errno);
1694
+ usbi_err(ctx, "failed to set timer for next timeout");
1668
1695
 
1669
1696
  usbi_mutex_lock(&itransfer->lock);
1670
1697
  itransfer->state_flags &= ~USBI_TRANSFER_IN_FLIGHT;
@@ -1676,7 +1703,7 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
1676
1703
  if (transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL)
1677
1704
  rqlen -= LIBUSB_CONTROL_SETUP_SIZE;
1678
1705
  if (rqlen != itransfer->transferred) {
1679
- usbi_dbg("interpreting short transfer as error");
1706
+ usbi_dbg(ctx, "interpreting short transfer as error");
1680
1707
  status = LIBUSB_TRANSFER_ERROR;
1681
1708
  }
1682
1709
  }
@@ -1684,14 +1711,13 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
1684
1711
  flags = transfer->flags;
1685
1712
  transfer->status = status;
1686
1713
  transfer->actual_length = itransfer->transferred;
1687
- usbi_dbg("transfer %p has callback %p", transfer, transfer->callback);
1714
+ usbi_dbg(ctx, "transfer %p has callback %p", transfer, transfer->callback);
1688
1715
  if (transfer->callback)
1689
1716
  transfer->callback(transfer);
1690
1717
  /* transfer might have been freed by the above call, do not use from
1691
1718
  * this point. */
1692
1719
  if (flags & LIBUSB_TRANSFER_FREE_TRANSFER)
1693
1720
  libusb_free_transfer(transfer);
1694
- libusb_unref_device(dev_handle->dev);
1695
1721
  return r;
1696
1722
  }
1697
1723
 
@@ -1701,41 +1727,42 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
1701
1727
  * Do not call this function with the usbi_transfer lock held. User-specified
1702
1728
  * callback functions may attempt to directly resubmit the transfer, which
1703
1729
  * will attempt to take the lock. */
1704
- int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer)
1730
+ int usbi_handle_transfer_cancellation(struct usbi_transfer *itransfer)
1705
1731
  {
1706
- struct libusb_context *ctx = ITRANSFER_CTX(transfer);
1732
+ struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
1707
1733
  uint8_t timed_out;
1708
1734
 
1709
1735
  usbi_mutex_lock(&ctx->flying_transfers_lock);
1710
- timed_out = transfer->timeout_flags & USBI_TRANSFER_TIMED_OUT;
1736
+ timed_out = itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT;
1711
1737
  usbi_mutex_unlock(&ctx->flying_transfers_lock);
1712
1738
 
1713
1739
  /* if the URB was cancelled due to timeout, report timeout to the user */
1714
1740
  if (timed_out) {
1715
- usbi_dbg("detected timeout cancellation");
1716
- return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_TIMED_OUT);
1741
+ usbi_dbg(ctx, "detected timeout cancellation");
1742
+ return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_TIMED_OUT);
1717
1743
  }
1718
1744
 
1719
1745
  /* otherwise its a normal async cancel */
1720
- return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_CANCELLED);
1746
+ return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_CANCELLED);
1721
1747
  }
1722
1748
 
1723
1749
  /* Add a completed transfer to the completed_transfers list of the
1724
1750
  * context and signal the event. The backend's handle_transfer_completion()
1725
1751
  * function will be called the next time an event handler runs. */
1726
- void usbi_signal_transfer_completion(struct usbi_transfer *transfer)
1752
+ void usbi_signal_transfer_completion(struct usbi_transfer *itransfer)
1727
1753
  {
1728
- libusb_device_handle *dev_handle = USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->dev_handle;
1754
+ struct libusb_device *dev = itransfer->dev;
1729
1755
 
1730
- if (dev_handle) {
1731
- struct libusb_context *ctx = HANDLE_CTX(dev_handle);
1732
- int pending_events;
1756
+ if (dev) {
1757
+ struct libusb_context *ctx = DEVICE_CTX(dev);
1758
+ unsigned int event_flags;
1733
1759
 
1734
1760
  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);
1761
+ event_flags = ctx->event_flags;
1762
+ ctx->event_flags |= USBI_EVENT_TRANSFER_COMPLETED;
1763
+ list_add_tail(&itransfer->completed_list, &ctx->completed_transfers);
1764
+ if (!event_flags)
1765
+ usbi_signal_event(&ctx->event);
1739
1766
  usbi_mutex_unlock(&ctx->event_data_lock);
1740
1767
  }
1741
1768
  }
@@ -1763,7 +1790,8 @@ int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
1763
1790
  {
1764
1791
  int r;
1765
1792
  unsigned int ru;
1766
- USBI_GET_CONTEXT(ctx);
1793
+
1794
+ ctx = usbi_get_context(ctx);
1767
1795
 
1768
1796
  /* is someone else waiting to close a device? if so, don't let this thread
1769
1797
  * start event handling */
@@ -1771,12 +1799,12 @@ int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
1771
1799
  ru = ctx->device_close;
1772
1800
  usbi_mutex_unlock(&ctx->event_data_lock);
1773
1801
  if (ru) {
1774
- usbi_dbg("someone else is closing a device");
1802
+ usbi_dbg(ctx, "someone else is closing a device");
1775
1803
  return 1;
1776
1804
  }
1777
1805
 
1778
1806
  r = usbi_mutex_trylock(&ctx->events_lock);
1779
- if (r)
1807
+ if (!r)
1780
1808
  return 1;
1781
1809
 
1782
1810
  ctx->event_handler_active = 1;
@@ -1803,7 +1831,7 @@ int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
1803
1831
  */
1804
1832
  void API_EXPORTED libusb_lock_events(libusb_context *ctx)
1805
1833
  {
1806
- USBI_GET_CONTEXT(ctx);
1834
+ ctx = usbi_get_context(ctx);
1807
1835
  usbi_mutex_lock(&ctx->events_lock);
1808
1836
  ctx->event_handler_active = 1;
1809
1837
  }
@@ -1818,7 +1846,7 @@ void API_EXPORTED libusb_lock_events(libusb_context *ctx)
1818
1846
  */
1819
1847
  void API_EXPORTED libusb_unlock_events(libusb_context *ctx)
1820
1848
  {
1821
- USBI_GET_CONTEXT(ctx);
1849
+ ctx = usbi_get_context(ctx);
1822
1850
  ctx->event_handler_active = 0;
1823
1851
  usbi_mutex_unlock(&ctx->events_lock);
1824
1852
 
@@ -1854,7 +1882,8 @@ void API_EXPORTED libusb_unlock_events(libusb_context *ctx)
1854
1882
  int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx)
1855
1883
  {
1856
1884
  unsigned int r;
1857
- USBI_GET_CONTEXT(ctx);
1885
+
1886
+ ctx = usbi_get_context(ctx);
1858
1887
 
1859
1888
  /* is someone else waiting to close a device? if so, don't let this thread
1860
1889
  * continue event handling */
@@ -1862,7 +1891,7 @@ int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx)
1862
1891
  r = ctx->device_close;
1863
1892
  usbi_mutex_unlock(&ctx->event_data_lock);
1864
1893
  if (r) {
1865
- usbi_dbg("someone else is closing a device");
1894
+ usbi_dbg(ctx, "someone else is closing a device");
1866
1895
  return 0;
1867
1896
  }
1868
1897
 
@@ -1882,7 +1911,8 @@ int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx)
1882
1911
  int API_EXPORTED libusb_event_handler_active(libusb_context *ctx)
1883
1912
  {
1884
1913
  unsigned int r;
1885
- USBI_GET_CONTEXT(ctx);
1914
+
1915
+ ctx = usbi_get_context(ctx);
1886
1916
 
1887
1917
  /* is someone else waiting to close a device? if so, don't let this thread
1888
1918
  * start event handling -- indicate that event handling is happening */
@@ -1890,7 +1920,7 @@ int API_EXPORTED libusb_event_handler_active(libusb_context *ctx)
1890
1920
  r = ctx->device_close;
1891
1921
  usbi_mutex_unlock(&ctx->event_data_lock);
1892
1922
  if (r) {
1893
- usbi_dbg("someone else is closing a device");
1923
+ usbi_dbg(ctx, "someone else is closing a device");
1894
1924
  return 1;
1895
1925
  }
1896
1926
 
@@ -1909,16 +1939,17 @@ int API_EXPORTED libusb_event_handler_active(libusb_context *ctx)
1909
1939
  */
1910
1940
  void API_EXPORTED libusb_interrupt_event_handler(libusb_context *ctx)
1911
1941
  {
1912
- int pending_events;
1913
- USBI_GET_CONTEXT(ctx);
1942
+ unsigned int event_flags;
1943
+
1944
+ usbi_dbg(ctx, " ");
1914
1945
 
1915
- usbi_dbg("");
1946
+ ctx = usbi_get_context(ctx);
1916
1947
  usbi_mutex_lock(&ctx->event_data_lock);
1917
1948
 
1918
- pending_events = usbi_pending_events(ctx);
1949
+ event_flags = ctx->event_flags;
1919
1950
  ctx->event_flags |= USBI_EVENT_USER_INTERRUPT;
1920
- if (!pending_events)
1921
- usbi_signal_event(ctx);
1951
+ if (!event_flags)
1952
+ usbi_signal_event(&ctx->event);
1922
1953
 
1923
1954
  usbi_mutex_unlock(&ctx->event_data_lock);
1924
1955
  }
@@ -1934,7 +1965,7 @@ void API_EXPORTED libusb_interrupt_event_handler(libusb_context *ctx)
1934
1965
  *
1935
1966
  * You only need to use this lock if you are developing an application
1936
1967
  * which calls poll() or select() on libusb's file descriptors directly,
1937
- * <b>and</b> may potentially be handling events from 2 threads simultaenously.
1968
+ * <b>and</b> may potentially be handling events from 2 threads simultaneously.
1938
1969
  * If you stick to libusb's event handling loop functions (e.g.
1939
1970
  * libusb_handle_events()) then you do not need to be concerned with this
1940
1971
  * locking.
@@ -1944,7 +1975,7 @@ void API_EXPORTED libusb_interrupt_event_handler(libusb_context *ctx)
1944
1975
  */
1945
1976
  void API_EXPORTED libusb_lock_event_waiters(libusb_context *ctx)
1946
1977
  {
1947
- USBI_GET_CONTEXT(ctx);
1978
+ ctx = usbi_get_context(ctx);
1948
1979
  usbi_mutex_lock(&ctx->event_waiters_lock);
1949
1980
  }
1950
1981
 
@@ -1955,7 +1986,7 @@ void API_EXPORTED libusb_lock_event_waiters(libusb_context *ctx)
1955
1986
  */
1956
1987
  void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx)
1957
1988
  {
1958
- USBI_GET_CONTEXT(ctx);
1989
+ ctx = usbi_get_context(ctx);
1959
1990
  usbi_mutex_unlock(&ctx->event_waiters_lock);
1960
1991
  }
1961
1992
 
@@ -1982,25 +2013,28 @@ void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx)
1982
2013
  * indicates unlimited timeout.
1983
2014
  * \returns 0 after a transfer completes or another thread stops event handling
1984
2015
  * \returns 1 if the timeout expired
2016
+ * \returns LIBUSB_ERROR_INVALID_PARAM if timeval is invalid
1985
2017
  * \ref libusb_mtasync
1986
2018
  */
1987
2019
  int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
1988
2020
  {
1989
2021
  int r;
1990
2022
 
1991
- USBI_GET_CONTEXT(ctx);
1992
- if (tv == NULL) {
2023
+ ctx = usbi_get_context(ctx);
2024
+ if (!tv) {
1993
2025
  usbi_cond_wait(&ctx->event_waiters_cond, &ctx->event_waiters_lock);
1994
2026
  return 0;
1995
2027
  }
1996
2028
 
2029
+ if (!TIMEVAL_IS_VALID(tv))
2030
+ return LIBUSB_ERROR_INVALID_PARAM;
2031
+
1997
2032
  r = usbi_cond_timedwait(&ctx->event_waiters_cond,
1998
2033
  &ctx->event_waiters_lock, tv);
1999
-
2000
2034
  if (r < 0)
2001
- return r;
2002
- else
2003
- return (r == ETIMEDOUT);
2035
+ return r == LIBUSB_ERROR_TIMEOUT;
2036
+
2037
+ return 0;
2004
2038
  }
2005
2039
 
2006
2040
  static void handle_timeout(struct usbi_transfer *itransfer)
@@ -2015,78 +2049,146 @@ static void handle_timeout(struct usbi_transfer *itransfer)
2015
2049
  itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
2016
2050
  else
2017
2051
  usbi_warn(TRANSFER_CTX(transfer),
2018
- "async cancel failed %d errno=%d", r, errno);
2052
+ "async cancel failed %d", r);
2019
2053
  }
2020
2054
 
2021
- static int handle_timeouts_locked(struct libusb_context *ctx)
2055
+ static void handle_timeouts_locked(struct libusb_context *ctx)
2022
2056
  {
2023
- int r;
2024
- struct timespec systime_ts;
2025
- struct timeval systime;
2026
- struct usbi_transfer *transfer;
2057
+ struct timespec systime;
2058
+ struct usbi_transfer *itransfer;
2027
2059
 
2028
2060
  if (list_empty(&ctx->flying_transfers))
2029
- return 0;
2061
+ return;
2030
2062
 
2031
2063
  /* get current time */
2032
- r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, &systime_ts);
2033
- if (r < 0)
2034
- return r;
2035
-
2036
- TIMESPEC_TO_TIMEVAL(&systime, &systime_ts);
2064
+ usbi_get_monotonic_time(&systime);
2037
2065
 
2038
2066
  /* iterate through flying transfers list, finding all transfers that
2039
2067
  * have expired timeouts */
2040
- list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2041
- struct timeval *cur_tv = &transfer->timeout;
2068
+ for_each_transfer(ctx, itransfer) {
2069
+ struct timespec *cur_ts = &itransfer->timeout;
2042
2070
 
2043
2071
  /* if we've reached transfers of infinite timeout, we're all done */
2044
- if (!timerisset(cur_tv))
2045
- return 0;
2072
+ if (!TIMESPEC_IS_SET(cur_ts))
2073
+ return;
2046
2074
 
2047
2075
  /* ignore timeouts we've already handled */
2048
- if (transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
2076
+ if (itransfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
2049
2077
  continue;
2050
2078
 
2051
2079
  /* if transfer has non-expired timeout, nothing more to do */
2052
- if ((cur_tv->tv_sec > systime.tv_sec) ||
2053
- (cur_tv->tv_sec == systime.tv_sec &&
2054
- cur_tv->tv_usec > systime.tv_usec))
2055
- return 0;
2080
+ if (TIMESPEC_CMP(cur_ts, &systime, >))
2081
+ return;
2056
2082
 
2057
2083
  /* otherwise, we've got an expired timeout to handle */
2058
- handle_timeout(transfer);
2084
+ handle_timeout(itransfer);
2059
2085
  }
2060
- return 0;
2061
2086
  }
2062
2087
 
2063
- static int handle_timeouts(struct libusb_context *ctx)
2088
+ static void handle_timeouts(struct libusb_context *ctx)
2064
2089
  {
2065
- int r;
2066
- USBI_GET_CONTEXT(ctx);
2090
+ ctx = usbi_get_context(ctx);
2067
2091
  usbi_mutex_lock(&ctx->flying_transfers_lock);
2068
- r = handle_timeouts_locked(ctx);
2092
+ handle_timeouts_locked(ctx);
2069
2093
  usbi_mutex_unlock(&ctx->flying_transfers_lock);
2094
+ }
2095
+
2096
+ static int handle_event_trigger(struct libusb_context *ctx)
2097
+ {
2098
+ struct list_head hotplug_msgs;
2099
+ int hotplug_event = 0;
2100
+ int r = 0;
2101
+
2102
+ usbi_dbg(ctx, "event triggered");
2103
+
2104
+ list_init(&hotplug_msgs);
2105
+
2106
+ /* take the the event data lock while processing events */
2107
+ usbi_mutex_lock(&ctx->event_data_lock);
2108
+
2109
+ /* check if someone modified the event sources */
2110
+ if (ctx->event_flags & USBI_EVENT_EVENT_SOURCES_MODIFIED)
2111
+ usbi_dbg(ctx, "someone updated the event sources");
2112
+
2113
+ if (ctx->event_flags & USBI_EVENT_USER_INTERRUPT) {
2114
+ usbi_dbg(ctx, "someone purposefully interrupted");
2115
+ ctx->event_flags &= ~USBI_EVENT_USER_INTERRUPT;
2116
+ }
2117
+
2118
+ if (ctx->event_flags & USBI_EVENT_HOTPLUG_CB_DEREGISTERED) {
2119
+ usbi_dbg(ctx, "someone unregistered a hotplug cb");
2120
+ ctx->event_flags &= ~USBI_EVENT_HOTPLUG_CB_DEREGISTERED;
2121
+ hotplug_event = 1;
2122
+ }
2123
+
2124
+ /* check if someone is closing a device */
2125
+ if (ctx->event_flags & USBI_EVENT_DEVICE_CLOSE)
2126
+ usbi_dbg(ctx, "someone is closing a device");
2127
+
2128
+ /* check for any pending hotplug messages */
2129
+ if (ctx->event_flags & USBI_EVENT_HOTPLUG_MSG_PENDING) {
2130
+ usbi_dbg(ctx, "hotplug message received");
2131
+ ctx->event_flags &= ~USBI_EVENT_HOTPLUG_MSG_PENDING;
2132
+ hotplug_event = 1;
2133
+ assert(!list_empty(&ctx->hotplug_msgs));
2134
+ list_cut(&hotplug_msgs, &ctx->hotplug_msgs);
2135
+ }
2136
+
2137
+ /* complete any pending transfers */
2138
+ if (ctx->event_flags & USBI_EVENT_TRANSFER_COMPLETED) {
2139
+ struct usbi_transfer *itransfer, *tmp;
2140
+ struct list_head completed_transfers;
2141
+
2142
+ assert(!list_empty(&ctx->completed_transfers));
2143
+ list_cut(&completed_transfers, &ctx->completed_transfers);
2144
+ usbi_mutex_unlock(&ctx->event_data_lock);
2145
+
2146
+ __for_each_completed_transfer_safe(&completed_transfers, itransfer, tmp) {
2147
+ list_del(&itransfer->completed_list);
2148
+ r = usbi_backend.handle_transfer_completion(itransfer);
2149
+ if (r) {
2150
+ usbi_err(ctx, "backend handle_transfer_completion failed with error %d", r);
2151
+ break;
2152
+ }
2153
+ }
2154
+
2155
+ usbi_mutex_lock(&ctx->event_data_lock);
2156
+ if (!list_empty(&completed_transfers)) {
2157
+ /* an error occurred, put the remaining transfers back on the list */
2158
+ list_splice_front(&completed_transfers, &ctx->completed_transfers);
2159
+ } else if (list_empty(&ctx->completed_transfers)) {
2160
+ ctx->event_flags &= ~USBI_EVENT_TRANSFER_COMPLETED;
2161
+ }
2162
+ }
2163
+
2164
+ /* if no further pending events, clear the event */
2165
+ if (!ctx->event_flags)
2166
+ usbi_clear_event(&ctx->event);
2167
+
2168
+ usbi_mutex_unlock(&ctx->event_data_lock);
2169
+
2170
+ /* process the hotplug events, if any */
2171
+ if (hotplug_event)
2172
+ usbi_hotplug_process(ctx, &hotplug_msgs);
2173
+
2070
2174
  return r;
2071
2175
  }
2072
2176
 
2073
- #ifdef USBI_TIMERFD_AVAILABLE
2074
- static int handle_timerfd_trigger(struct libusb_context *ctx)
2177
+ #ifdef HAVE_OS_TIMER
2178
+ static int handle_timer_trigger(struct libusb_context *ctx)
2075
2179
  {
2076
2180
  int r;
2077
2181
 
2078
2182
  usbi_mutex_lock(&ctx->flying_transfers_lock);
2079
2183
 
2080
2184
  /* process the timeout that just happened */
2081
- r = handle_timeouts_locked(ctx);
2082
- if (r < 0)
2083
- goto out;
2185
+ handle_timeouts_locked(ctx);
2084
2186
 
2085
- /* arm for next timeout*/
2086
- r = arm_timerfd_for_next_timeout(ctx);
2187
+ /* arm for next timeout */
2188
+ r = arm_timer_for_next_timeout(ctx);
2087
2189
 
2088
- out:
2089
2190
  usbi_mutex_unlock(&ctx->flying_transfers_lock);
2191
+
2090
2192
  return r;
2091
2193
  }
2092
2194
  #endif
@@ -2095,81 +2197,38 @@ out:
2095
2197
  * doing the same thing. */
2096
2198
  static int handle_events(struct libusb_context *ctx, struct timeval *tv)
2097
2199
  {
2098
- int r;
2099
- struct usbi_pollfd *ipollfd;
2100
- POLL_NFDS_TYPE nfds = 0;
2101
- POLL_NFDS_TYPE internal_nfds;
2102
- struct pollfd *fds = NULL;
2103
- int i = -1;
2104
- int timeout_ms;
2200
+ struct usbi_reported_events reported_events;
2201
+ int r, timeout_ms;
2105
2202
 
2106
2203
  /* prevent attempts to recursively handle events (e.g. calling into
2107
2204
  * libusb_handle_events() from within a hotplug or transfer callback) */
2108
- usbi_mutex_lock(&ctx->event_data_lock);
2109
- r = 0;
2110
2205
  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;
2118
-
2119
- /* there are certain fds that libusb uses internally, currently:
2120
- *
2121
- * 1) event pipe
2122
- * 2) timerfd
2123
- *
2124
- * the backend will never need to attempt to handle events on these fds, so
2125
- * we determine how many fds are in use internally for this context and when
2126
- * handle_events() is called in the backend, the pollfd list and count will
2127
- * be adjusted to skip over these internal fds */
2128
- if (usbi_using_timerfd(ctx))
2129
- internal_nfds = 2;
2130
- else
2131
- internal_nfds = 1;
2206
+ return LIBUSB_ERROR_BUSY;
2132
2207
 
2133
- /* only reallocate the poll fds when the list of poll fds has been modified
2134
- * since the last poll, otherwise reuse them to save the additional overhead */
2208
+ /* only reallocate the event source data when the list of event sources has
2209
+ * been modified since the last handle_events(), otherwise reuse them to
2210
+ * save the additional overhead */
2135
2211
  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) {
2139
- usbi_dbg("poll fds modified, reallocating");
2212
+ if (ctx->event_flags & USBI_EVENT_EVENT_SOURCES_MODIFIED) {
2213
+ usbi_dbg(ctx, "event sources modified, reallocating event data");
2140
2214
 
2141
- free(ctx->pollfds);
2142
- ctx->pollfds = NULL;
2215
+ /* free anything removed since we last ran */
2216
+ cleanup_removed_event_sources(ctx);
2143
2217
 
2144
- /* sanity check - it is invalid for a context to have fewer than the
2145
- * required internal fds (memory corruption?) */
2146
- assert(ctx->pollfds_cnt >= internal_nfds);
2147
-
2148
- ctx->pollfds = calloc(ctx->pollfds_cnt, sizeof(*ctx->pollfds));
2149
- if (!ctx->pollfds) {
2218
+ r = usbi_alloc_event_data(ctx);
2219
+ if (r) {
2150
2220
  usbi_mutex_unlock(&ctx->event_data_lock);
2151
- r = LIBUSB_ERROR_NO_MEM;
2152
- goto done;
2153
- }
2154
-
2155
- list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) {
2156
- struct libusb_pollfd *pollfd = &ipollfd->pollfd;
2157
- i++;
2158
- ctx->pollfds[i].fd = pollfd->fd;
2159
- ctx->pollfds[i].events = pollfd->events;
2221
+ return r;
2160
2222
  }
2161
2223
 
2162
2224
  /* reset the flag now that we have the updated list */
2163
- ctx->event_flags &= ~USBI_EVENT_POLLFDS_MODIFIED;
2225
+ ctx->event_flags &= ~USBI_EVENT_EVENT_SOURCES_MODIFIED;
2164
2226
 
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);
2227
+ /* if no further pending events, clear the event so that we do
2228
+ * not immediately return from the wait function */
2229
+ if (!ctx->event_flags)
2230
+ usbi_clear_event(&ctx->event);
2169
2231
  }
2170
- fds = ctx->pollfds;
2171
- nfds = ctx->pollfds_cnt;
2172
- usbi_inc_fds_ref(fds, nfds);
2173
2232
  usbi_mutex_unlock(&ctx->event_data_lock);
2174
2233
 
2175
2234
  timeout_ms = (int)(tv->tv_sec * 1000) + (tv->tv_usec / 1000);
@@ -2178,145 +2237,47 @@ static int handle_events(struct libusb_context *ctx, struct timeval *tv)
2178
2237
  if (tv->tv_usec % 1000)
2179
2238
  timeout_ms++;
2180
2239
 
2181
- usbi_dbg("poll() %d fds with timeout in %dms", (int)nfds, timeout_ms);
2182
- r = usbi_poll(fds, nfds, timeout_ms);
2183
- usbi_dbg("poll() returned %d", r);
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;
2194
- }
2195
-
2196
- /* fds[0] is always the event pipe */
2197
- if (fds[0].revents) {
2198
- struct list_head hotplug_msgs;
2199
- struct usbi_transfer *itransfer;
2200
- int hotplug_cb_deregistered = 0;
2201
- int ret = 0;
2202
-
2203
- list_init(&hotplug_msgs);
2204
-
2205
- usbi_dbg("caught a fish on the event pipe");
2206
-
2207
- /* take the the event data lock while processing events */
2208
- usbi_mutex_lock(&ctx->event_data_lock);
2209
-
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;
2217
- }
2218
-
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);
2240
+ reported_events.event_bits = 0;
2249
2241
 
2250
- usbi_mutex_unlock(&ctx->event_data_lock);
2251
-
2252
- if (hotplug_cb_deregistered)
2253
- usbi_hotplug_deregister(ctx, 0);
2254
-
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);
2242
+ usbi_start_event_handling(ctx);
2259
2243
 
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);
2244
+ r = usbi_wait_for_events(ctx, &reported_events, timeout_ms);
2245
+ if (r != LIBUSB_SUCCESS) {
2246
+ if (r == LIBUSB_ERROR_TIMEOUT) {
2247
+ handle_timeouts(ctx);
2248
+ r = LIBUSB_SUCCESS;
2268
2249
  }
2250
+ goto done;
2251
+ }
2269
2252
 
2270
- if (ret) {
2253
+ if (reported_events.event_triggered) {
2254
+ r = handle_event_trigger(ctx);
2255
+ if (r) {
2271
2256
  /* return error code */
2272
- r = ret;
2273
2257
  goto done;
2274
2258
  }
2275
-
2276
- if (0 == --r)
2277
- goto done;
2278
2259
  }
2279
2260
 
2280
- #ifdef USBI_TIMERFD_AVAILABLE
2281
- /* on timerfd configurations, fds[1] is the timerfd */
2282
- if (usbi_using_timerfd(ctx) && fds[1].revents) {
2283
- /* timerfd indicates that a timeout has expired */
2284
- int ret;
2285
- usbi_dbg("timerfd triggered");
2286
-
2287
- ret = handle_timerfd_trigger(ctx);
2288
- if (ret < 0) {
2261
+ #ifdef HAVE_OS_TIMER
2262
+ if (reported_events.timer_triggered) {
2263
+ r = handle_timer_trigger(ctx);
2264
+ if (r) {
2289
2265
  /* return error code */
2290
- r = ret;
2291
2266
  goto done;
2292
2267
  }
2293
-
2294
- if (0 == --r)
2295
- goto done;
2296
2268
  }
2297
2269
  #endif
2298
2270
 
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
- }
2271
+ if (!reported_events.num_ready)
2272
+ goto done;
2312
2273
 
2313
- r = usbi_backend.handle_events(ctx, fds + internal_nfds, nfds - internal_nfds, r);
2274
+ r = usbi_backend.handle_events(ctx, reported_events.event_data,
2275
+ reported_events.event_data_count, reported_events.num_ready);
2314
2276
  if (r)
2315
2277
  usbi_err(ctx, "backend handle_events failed with error %d", r);
2316
2278
 
2317
2279
  done:
2318
2280
  usbi_end_event_handling(ctx);
2319
- usbi_dec_fds_ref(fds, nfds);
2320
2281
  return r;
2321
2282
  }
2322
2283
 
@@ -2370,7 +2331,9 @@ static int get_next_timeout(libusb_context *ctx, struct timeval *tv,
2370
2331
  * \param tv the maximum time to block waiting for events, or an all zero
2371
2332
  * timeval struct for non-blocking mode
2372
2333
  * \param completed pointer to completion integer to check, or NULL
2373
- * \returns 0 on success, or a LIBUSB_ERROR code on failure
2334
+ * \returns 0 on success
2335
+ * \returns LIBUSB_ERROR_INVALID_PARAM if timeval is invalid
2336
+ * \returns another LIBUSB_ERROR code on other failure
2374
2337
  * \ref libusb_mtasync
2375
2338
  */
2376
2339
  int API_EXPORTED libusb_handle_events_timeout_completed(libusb_context *ctx,
@@ -2379,18 +2342,22 @@ int API_EXPORTED libusb_handle_events_timeout_completed(libusb_context *ctx,
2379
2342
  int r;
2380
2343
  struct timeval poll_timeout;
2381
2344
 
2382
- USBI_GET_CONTEXT(ctx);
2345
+ if (!TIMEVAL_IS_VALID(tv))
2346
+ return LIBUSB_ERROR_INVALID_PARAM;
2347
+
2348
+ ctx = usbi_get_context(ctx);
2383
2349
  r = get_next_timeout(ctx, tv, &poll_timeout);
2384
2350
  if (r) {
2385
2351
  /* timeout already expired */
2386
- return handle_timeouts(ctx);
2352
+ handle_timeouts(ctx);
2353
+ return 0;
2387
2354
  }
2388
2355
 
2389
2356
  retry:
2390
2357
  if (libusb_try_lock_events(ctx) == 0) {
2391
2358
  if (completed == NULL || !*completed) {
2392
2359
  /* we obtained the event lock: do our own event handling */
2393
- usbi_dbg("doing our own event handling");
2360
+ usbi_dbg(ctx, "doing our own event handling");
2394
2361
  r = handle_events(ctx, &poll_timeout);
2395
2362
  }
2396
2363
  libusb_unlock_events(ctx);
@@ -2408,11 +2375,11 @@ retry:
2408
2375
  /* we hit a race: whoever was event handling earlier finished in the
2409
2376
  * time it took us to reach this point. try the cycle again. */
2410
2377
  libusb_unlock_event_waiters(ctx);
2411
- usbi_dbg("event handler was active but went away, retrying");
2378
+ usbi_dbg(ctx, "event handler was active but went away, retrying");
2412
2379
  goto retry;
2413
2380
  }
2414
2381
 
2415
- usbi_dbg("another thread is doing event handling");
2382
+ usbi_dbg(ctx, "another thread is doing event handling");
2416
2383
  r = libusb_wait_for_event(ctx, &poll_timeout);
2417
2384
 
2418
2385
  already_done:
@@ -2421,9 +2388,8 @@ already_done:
2421
2388
  if (r < 0)
2422
2389
  return r;
2423
2390
  else if (r == 1)
2424
- return handle_timeouts(ctx);
2425
- else
2426
- return 0;
2391
+ handle_timeouts(ctx);
2392
+ return 0;
2427
2393
  }
2428
2394
 
2429
2395
  /** \ingroup libusb_poll
@@ -2450,7 +2416,7 @@ int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx,
2450
2416
 
2451
2417
  /** \ingroup libusb_poll
2452
2418
  * Handle any pending events in blocking mode. There is currently a timeout
2453
- * hardcoded at 60 seconds but we plan to make it unlimited in future. For
2419
+ * hard-coded at 60 seconds but we plan to make it unlimited in future. For
2454
2420
  * finer control over whether this function is blocking or non-blocking, or
2455
2421
  * for control over the timeout, use libusb_handle_events_timeout_completed()
2456
2422
  * instead.
@@ -2507,7 +2473,9 @@ int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx,
2507
2473
  * \param ctx the context to operate on, or NULL for the default context
2508
2474
  * \param tv the maximum time to block waiting for events, or zero for
2509
2475
  * non-blocking mode
2510
- * \returns 0 on success, or a LIBUSB_ERROR code on failure
2476
+ * \returns 0 on success
2477
+ * \returns LIBUSB_ERROR_INVALID_PARAM if timeval is invalid
2478
+ * \returns another LIBUSB_ERROR code on other failure
2511
2479
  * \ref libusb_mtasync
2512
2480
  */
2513
2481
  int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx,
@@ -2516,11 +2484,15 @@ int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx,
2516
2484
  int r;
2517
2485
  struct timeval poll_timeout;
2518
2486
 
2519
- USBI_GET_CONTEXT(ctx);
2487
+ if (!TIMEVAL_IS_VALID(tv))
2488
+ return LIBUSB_ERROR_INVALID_PARAM;
2489
+
2490
+ ctx = usbi_get_context(ctx);
2520
2491
  r = get_next_timeout(ctx, tv, &poll_timeout);
2521
2492
  if (r) {
2522
2493
  /* timeout already expired */
2523
- return handle_timeouts(ctx);
2494
+ handle_timeouts(ctx);
2495
+ return 0;
2524
2496
  }
2525
2497
 
2526
2498
  return handle_events(ctx, &poll_timeout);
@@ -2556,13 +2528,8 @@ int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx,
2556
2528
  */
2557
2529
  int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx)
2558
2530
  {
2559
- #if defined(USBI_TIMERFD_AVAILABLE)
2560
- USBI_GET_CONTEXT(ctx);
2561
- return usbi_using_timerfd(ctx);
2562
- #else
2563
- UNUSED(ctx);
2564
- return 0;
2565
- #endif
2531
+ ctx = usbi_get_context(ctx);
2532
+ return usbi_using_timer(ctx);
2566
2533
  }
2567
2534
 
2568
2535
  /** \ingroup libusb_poll
@@ -2596,55 +2563,49 @@ int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx)
2596
2563
  int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
2597
2564
  struct timeval *tv)
2598
2565
  {
2599
- struct usbi_transfer *transfer;
2600
- struct timespec cur_ts;
2601
- struct timeval cur_tv;
2602
- struct timeval next_timeout = { 0, 0 };
2603
- int r;
2566
+ struct usbi_transfer *itransfer;
2567
+ struct timespec systime;
2568
+ struct timespec next_timeout = { 0, 0 };
2604
2569
 
2605
- USBI_GET_CONTEXT(ctx);
2606
- if (usbi_using_timerfd(ctx))
2570
+ ctx = usbi_get_context(ctx);
2571
+ if (usbi_using_timer(ctx))
2607
2572
  return 0;
2608
2573
 
2609
2574
  usbi_mutex_lock(&ctx->flying_transfers_lock);
2610
2575
  if (list_empty(&ctx->flying_transfers)) {
2611
2576
  usbi_mutex_unlock(&ctx->flying_transfers_lock);
2612
- usbi_dbg("no URBs, no timeout!");
2577
+ usbi_dbg(ctx, "no URBs, no timeout!");
2613
2578
  return 0;
2614
2579
  }
2615
2580
 
2616
2581
  /* find next transfer which hasn't already been processed as timed out */
2617
- list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
2618
- if (transfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
2582
+ for_each_transfer(ctx, itransfer) {
2583
+ if (itransfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))
2619
2584
  continue;
2620
2585
 
2621
- /* if we've reached transfers of infinte timeout, we're done looking */
2622
- if (!timerisset(&transfer->timeout))
2586
+ /* if we've reached transfers of infinite timeout, we're done looking */
2587
+ if (!TIMESPEC_IS_SET(&itransfer->timeout))
2623
2588
  break;
2624
2589
 
2625
- next_timeout = transfer->timeout;
2590
+ next_timeout = itransfer->timeout;
2626
2591
  break;
2627
2592
  }
2628
2593
  usbi_mutex_unlock(&ctx->flying_transfers_lock);
2629
2594
 
2630
- if (!timerisset(&next_timeout)) {
2631
- usbi_dbg("no URB with timeout or all handled by OS; no timeout!");
2595
+ if (!TIMESPEC_IS_SET(&next_timeout)) {
2596
+ usbi_dbg(ctx, "no URB with timeout or all handled by OS; no timeout!");
2632
2597
  return 0;
2633
2598
  }
2634
2599
 
2635
- r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts);
2636
- if (r < 0) {
2637
- usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno);
2638
- return 0;
2639
- }
2640
- TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts);
2600
+ usbi_get_monotonic_time(&systime);
2641
2601
 
2642
- if (!timercmp(&cur_tv, &next_timeout, <)) {
2643
- usbi_dbg("first timeout already expired");
2602
+ if (!TIMESPEC_CMP(&systime, &next_timeout, <)) {
2603
+ usbi_dbg(ctx, "first timeout already expired");
2644
2604
  timerclear(tv);
2645
2605
  } else {
2646
- timersub(&next_timeout, &cur_tv, tv);
2647
- usbi_dbg("next timeout in %ld.%06lds", (long)tv->tv_sec, (long)tv->tv_usec);
2606
+ TIMESPEC_SUB(&next_timeout, &systime, &next_timeout);
2607
+ TIMESPEC_TO_TIMEVAL(tv, &next_timeout);
2608
+ usbi_dbg(ctx, "next timeout in %ld.%06lds", (long)tv->tv_sec, (long)tv->tv_usec);
2648
2609
  }
2649
2610
 
2650
2611
  return 1;
@@ -2675,79 +2636,92 @@ void API_EXPORTED libusb_set_pollfd_notifiers(libusb_context *ctx,
2675
2636
  libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb,
2676
2637
  void *user_data)
2677
2638
  {
2678
- USBI_GET_CONTEXT(ctx);
2639
+ #if !defined(PLATFORM_WINDOWS)
2640
+ ctx = usbi_get_context(ctx);
2679
2641
  ctx->fd_added_cb = added_cb;
2680
2642
  ctx->fd_removed_cb = removed_cb;
2681
2643
  ctx->fd_cb_user_data = user_data;
2644
+ #else
2645
+ usbi_err(ctx, "external polling of libusb's internal event sources " \
2646
+ "is not yet supported on Windows");
2647
+ UNUSED(added_cb);
2648
+ UNUSED(removed_cb);
2649
+ UNUSED(user_data);
2650
+ #endif
2682
2651
  }
2683
2652
 
2684
2653
  /*
2685
2654
  * 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.
2655
+ * up the event source change. Callers of this function must hold the event_data_lock.
2687
2656
  */
2688
- static void usbi_fd_notification(struct libusb_context *ctx)
2657
+ static void usbi_event_source_notification(struct libusb_context *ctx)
2689
2658
  {
2690
- int pending_events;
2659
+ unsigned int event_flags;
2691
2660
 
2692
2661
  /* Record that there is a new poll fd.
2693
2662
  * 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);
2663
+ event_flags = ctx->event_flags;
2664
+ ctx->event_flags |= USBI_EVENT_EVENT_SOURCES_MODIFIED;
2665
+ if (!event_flags)
2666
+ usbi_signal_event(&ctx->event);
2698
2667
  }
2699
2668
 
2700
- /* Add a file descriptor to the list of file descriptors to be monitored.
2701
- * events should be specified as a bitmask of events passed to poll(), e.g.
2669
+ /* Add an event source to the list of event sources to be monitored.
2670
+ * poll_events should be specified as a bitmask of events passed to poll(), e.g.
2702
2671
  * POLLIN and/or POLLOUT. */
2703
- int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events)
2672
+ int usbi_add_event_source(struct libusb_context *ctx, usbi_os_handle_t os_handle, short poll_events)
2704
2673
  {
2705
- struct usbi_pollfd *ipollfd = malloc(sizeof(*ipollfd));
2706
- if (!ipollfd)
2674
+ struct usbi_event_source *ievent_source = malloc(sizeof(*ievent_source));
2675
+
2676
+ if (!ievent_source)
2707
2677
  return LIBUSB_ERROR_NO_MEM;
2708
2678
 
2709
- usbi_dbg("add fd %d events %d", fd, events);
2710
- ipollfd->pollfd.fd = fd;
2711
- ipollfd->pollfd.events = events;
2679
+ usbi_dbg(ctx, "add " USBI_OS_HANDLE_FORMAT_STRING " events %d", os_handle, poll_events);
2680
+ ievent_source->data.os_handle = os_handle;
2681
+ ievent_source->data.poll_events = poll_events;
2712
2682
  usbi_mutex_lock(&ctx->event_data_lock);
2713
- list_add_tail(&ipollfd->list, &ctx->ipollfds);
2714
- ctx->pollfds_cnt++;
2715
- usbi_fd_notification(ctx);
2683
+ list_add_tail(&ievent_source->list, &ctx->event_sources);
2684
+ usbi_event_source_notification(ctx);
2716
2685
  usbi_mutex_unlock(&ctx->event_data_lock);
2717
2686
 
2687
+ #if !defined(PLATFORM_WINDOWS)
2718
2688
  if (ctx->fd_added_cb)
2719
- ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data);
2689
+ ctx->fd_added_cb(os_handle, poll_events, ctx->fd_cb_user_data);
2690
+ #endif
2691
+
2720
2692
  return 0;
2721
2693
  }
2722
2694
 
2723
- /* Remove a file descriptor from the list of file descriptors to be polled. */
2724
- void usbi_remove_pollfd(struct libusb_context *ctx, int fd)
2695
+ /* Remove an event source from the list of event sources to be monitored. */
2696
+ void usbi_remove_event_source(struct libusb_context *ctx, usbi_os_handle_t os_handle)
2725
2697
  {
2726
- struct usbi_pollfd *ipollfd;
2698
+ struct usbi_event_source *ievent_source;
2727
2699
  int found = 0;
2728
2700
 
2729
- usbi_dbg("remove fd %d", fd);
2701
+ usbi_dbg(ctx, "remove " USBI_OS_HANDLE_FORMAT_STRING, os_handle);
2730
2702
  usbi_mutex_lock(&ctx->event_data_lock);
2731
- list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd)
2732
- if (ipollfd->pollfd.fd == fd) {
2703
+ for_each_event_source(ctx, ievent_source) {
2704
+ if (ievent_source->data.os_handle == os_handle) {
2733
2705
  found = 1;
2734
2706
  break;
2735
2707
  }
2708
+ }
2736
2709
 
2737
2710
  if (!found) {
2738
- usbi_dbg("couldn't find fd %d to remove", fd);
2711
+ usbi_dbg(ctx, "couldn't find " USBI_OS_HANDLE_FORMAT_STRING " to remove", os_handle);
2739
2712
  usbi_mutex_unlock(&ctx->event_data_lock);
2740
2713
  return;
2741
2714
  }
2742
2715
 
2743
- list_del(&ipollfd->list);
2744
- list_add_tail(&ipollfd->list, &ctx->removed_ipollfds);
2745
- ctx->pollfds_cnt--;
2746
- usbi_fd_notification(ctx);
2716
+ list_del(&ievent_source->list);
2717
+ list_add_tail(&ievent_source->list, &ctx->removed_event_sources);
2718
+ usbi_event_source_notification(ctx);
2747
2719
  usbi_mutex_unlock(&ctx->event_data_lock);
2748
2720
 
2721
+ #if !defined(PLATFORM_WINDOWS)
2749
2722
  if (ctx->fd_removed_cb)
2750
- ctx->fd_removed_cb(fd, ctx->fd_cb_user_data);
2723
+ ctx->fd_removed_cb(os_handle, ctx->fd_cb_user_data);
2724
+ #endif
2751
2725
  }
2752
2726
 
2753
2727
  /** \ingroup libusb_poll
@@ -2769,28 +2743,36 @@ DEFAULT_VISIBILITY
2769
2743
  const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds(
2770
2744
  libusb_context *ctx)
2771
2745
  {
2772
- #ifndef OS_WINDOWS
2746
+ #if !defined(PLATFORM_WINDOWS)
2773
2747
  struct libusb_pollfd **ret = NULL;
2774
- struct usbi_pollfd *ipollfd;
2775
- size_t i = 0;
2776
- USBI_GET_CONTEXT(ctx);
2748
+ struct usbi_event_source *ievent_source;
2749
+ size_t i;
2750
+
2751
+ static_assert(sizeof(struct usbi_event_source_data) == sizeof(struct libusb_pollfd),
2752
+ "mismatch between usbi_event_source_data and libusb_pollfd sizes");
2753
+
2754
+ ctx = usbi_get_context(ctx);
2777
2755
 
2778
2756
  usbi_mutex_lock(&ctx->event_data_lock);
2779
2757
 
2780
- ret = calloc(ctx->pollfds_cnt + 1, sizeof(struct libusb_pollfd *));
2758
+ i = 0;
2759
+ for_each_event_source(ctx, ievent_source)
2760
+ i++;
2761
+
2762
+ ret = calloc(i + 1, sizeof(struct libusb_pollfd *));
2781
2763
  if (!ret)
2782
2764
  goto out;
2783
2765
 
2784
- list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd)
2785
- ret[i++] = (struct libusb_pollfd *) ipollfd;
2786
- ret[ctx->pollfds_cnt] = NULL;
2766
+ i = 0;
2767
+ for_each_event_source(ctx, ievent_source)
2768
+ ret[i++] = (struct libusb_pollfd *)ievent_source;
2787
2769
 
2788
2770
  out:
2789
2771
  usbi_mutex_unlock(&ctx->event_data_lock);
2790
- return (const struct libusb_pollfd **) ret;
2772
+ return (const struct libusb_pollfd **)ret;
2791
2773
  #else
2792
- usbi_err(ctx, "external polling of libusb's internal descriptors "\
2793
- "is not yet supported on Windows platforms");
2774
+ usbi_err(ctx, "external polling of libusb's internal event sources " \
2775
+ "is not yet supported on Windows");
2794
2776
  return NULL;
2795
2777
  #endif
2796
2778
  }
@@ -2808,7 +2790,11 @@ out:
2808
2790
  */
2809
2791
  void API_EXPORTED libusb_free_pollfds(const struct libusb_pollfd **pollfds)
2810
2792
  {
2793
+ #if !defined(PLATFORM_WINDOWS)
2811
2794
  free((void *)pollfds);
2795
+ #else
2796
+ UNUSED(pollfds);
2797
+ #endif
2812
2798
  }
2813
2799
 
2814
2800
  /* Backends may call this from handle_events to report disconnection of a
@@ -2817,10 +2803,11 @@ void API_EXPORTED libusb_free_pollfds(const struct libusb_pollfd **pollfds)
2817
2803
  */
2818
2804
  void usbi_handle_disconnect(struct libusb_device_handle *dev_handle)
2819
2805
  {
2806
+ struct libusb_context *ctx = HANDLE_CTX(dev_handle);
2820
2807
  struct usbi_transfer *cur;
2821
2808
  struct usbi_transfer *to_cancel;
2822
2809
 
2823
- usbi_dbg("device %d.%d",
2810
+ usbi_dbg(ctx, "device %d.%d",
2824
2811
  dev_handle->dev->bus_number, dev_handle->dev->device_address);
2825
2812
 
2826
2813
  /* terminate all pending transfers with the LIBUSB_TRANSFER_NO_DEVICE
@@ -2838,8 +2825,8 @@ void usbi_handle_disconnect(struct libusb_device_handle *dev_handle)
2838
2825
 
2839
2826
  while (1) {
2840
2827
  to_cancel = NULL;
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)
2828
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
2829
+ for_each_transfer(ctx, cur) {
2843
2830
  if (USBI_TRANSFER_TO_LIBUSB_TRANSFER(cur)->dev_handle == dev_handle) {
2844
2831
  usbi_mutex_lock(&cur->lock);
2845
2832
  if (cur->state_flags & USBI_TRANSFER_IN_FLIGHT)
@@ -2849,12 +2836,13 @@ void usbi_handle_disconnect(struct libusb_device_handle *dev_handle)
2849
2836
  if (to_cancel)
2850
2837
  break;
2851
2838
  }
2852
- usbi_mutex_unlock(&HANDLE_CTX(dev_handle)->flying_transfers_lock);
2839
+ }
2840
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
2853
2841
 
2854
2842
  if (!to_cancel)
2855
2843
  break;
2856
2844
 
2857
- usbi_dbg("cancelling transfer %p from disconnect",
2845
+ usbi_dbg(ctx, "cancelling transfer %p from disconnect",
2858
2846
  USBI_TRANSFER_TO_LIBUSB_TRANSFER(to_cancel));
2859
2847
 
2860
2848
  usbi_mutex_lock(&to_cancel->lock);
@@ -2862,5 +2850,4 @@ void usbi_handle_disconnect(struct libusb_device_handle *dev_handle)
2862
2850
  usbi_mutex_unlock(&to_cancel->lock);
2863
2851
  usbi_handle_transfer_completion(to_cancel, LIBUSB_TRANSFER_NO_DEVICE);
2864
2852
  }
2865
-
2866
2853
  }