libusb-1.0.25.patch 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. From b5a7dca8cba163ca15b873c3ac9c81ec5622e827 Mon Sep 17 00:00:00 2001
  2. From: osy <50960678+osy@users.noreply.github.com>
  3. Date: Sat, 15 May 2021 23:29:54 -0700
  4. Subject: [PATCH 1/3] darwin: reset by re-enumerate on non-macOS platforms
  5. On non-macOS platforms, ResetDevice() does nothing so we use the "old" way of
  6. calling re-enumerate. If the device is captured, we have to re-enumerate, then
  7. re-capture, re-authorize, and finally restore the state.
  8. ---
  9. libusb/os/darwin_usb.c | 28 ++++++++++++++++++++++++++--
  10. 1 file changed, 26 insertions(+), 2 deletions(-)
  11. diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
  12. index 903422c6..c2a48135 100644
  13. --- a/libusb/os/darwin_usb.c
  14. +++ b/libusb/os/darwin_usb.c
  15. @@ -95,6 +95,8 @@ static enum libusb_error process_new_device (struct libusb_context *ctx, struct
  16. static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
  17. UInt64 *old_session_id);
  18. +static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, uint8_t interface);
  19. +
  20. #if defined(ENABLE_LOGGING)
  21. static const char *darwin_error_str (IOReturn result) {
  22. static char string_buffer[50];
  23. @@ -1842,15 +1844,37 @@ static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, b
  24. static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
  25. struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
  26. + unsigned long claimed_interfaces = dev_handle->claimed_interfaces;
  27. + int8_t active_config = dpriv->active_config;
  28. + int capture_count;
  29. IOReturn kresult;
  30. + enum libusb_error ret;
  31. +#if TARGET_OS_OSX
  32. + /* ResetDevice() is missing on non-macOS platforms */
  33. if (dpriv->capture_count > 0) {
  34. /* we have to use ResetDevice as USBDeviceReEnumerate() loses the authorization for capture */
  35. kresult = (*(dpriv->device))->ResetDevice (dpriv->device);
  36. return darwin_to_libusb (kresult);
  37. - } else {
  38. - return darwin_reenumerate_device (dev_handle, false);
  39. }
  40. +#endif
  41. + ret = darwin_reenumerate_device (dev_handle, false);
  42. + if ((ret == LIBUSB_SUCCESS || ret == LIBUSB_ERROR_NOT_FOUND) && dpriv->capture_count > 0) {
  43. + /* save old capture_count */
  44. + capture_count = dpriv->capture_count;
  45. + /* reset capture count */
  46. + dpriv->capture_count = 0;
  47. + /* attempt to detach kernel driver again as it is now re-attached */
  48. + ret = darwin_detach_kernel_driver (dev_handle, 0);
  49. + if (ret != LIBUSB_SUCCESS) {
  50. + return ret;
  51. + }
  52. + /* restore capture_count */
  53. + dpriv->capture_count = capture_count;
  54. + /* restore configuration */
  55. + ret = darwin_restore_state (dev_handle, active_config, claimed_interfaces);
  56. + }
  57. + return ret;
  58. }
  59. static io_service_t usb_find_interface_matching_location (const io_name_t class_name, UInt8 interface_number, UInt32 location) {
  60. --
  61. 2.41.0
  62. From c6cfa4b7eac9aed6228ac627531d54e2cefadf22 Mon Sep 17 00:00:00 2001
  63. From: Benjamin Berg <bberg@redhat.com>
  64. Date: Thu, 7 Apr 2022 12:43:08 +0200
  65. Subject: [PATCH 2/3] darwin: Fix crash in log handler when stopping event
  66. thread
  67. The darwin event thread (in contrast to other OS implementations) tries
  68. to log to the context that created it. However, this context is only
  69. guaranteed to be valid until the thread has started. It may be that
  70. another context is the last one to be destroyed, causing the event
  71. thread to log using an already destroyed context.
  72. Fix this by only passing on ctx where it is acceptable.
  73. Fixes #1108
  74. ---
  75. libusb/os/darwin_usb.c | 7 ++++---
  76. 1 file changed, 4 insertions(+), 3 deletions(-)
  77. diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
  78. index c2a48135..2c273e3a 100644
  79. --- a/libusb/os/darwin_usb.c
  80. +++ b/libusb/os/darwin_usb.c
  81. @@ -495,6 +495,7 @@ static void *darwin_event_thread_main (void *arg0) {
  82. io_iterator_t libusb_rem_device_iterator;
  83. io_iterator_t libusb_add_device_iterator;
  84. + /* ctx must only be used for logging during thread startup */
  85. usbi_dbg (ctx, "creating hotplug event source");
  86. runloop = CFRunLoopGetCurrent ();
  87. @@ -516,7 +517,7 @@ static void *darwin_event_thread_main (void *arg0) {
  88. kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
  89. IOServiceMatching(darwin_device_class),
  90. darwin_devices_detached,
  91. - ctx, &libusb_rem_device_iterator);
  92. + NULL, &libusb_rem_device_iterator);
  93. if (kresult != kIOReturnSuccess) {
  94. usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
  95. @@ -529,7 +530,7 @@ static void *darwin_event_thread_main (void *arg0) {
  96. kresult = IOServiceAddMatchingNotification(libusb_notification_port, kIOFirstMatchNotification,
  97. IOServiceMatching(darwin_device_class),
  98. darwin_devices_attached,
  99. - ctx, &libusb_add_device_iterator);
  100. + NULL, &libusb_add_device_iterator);
  101. if (kresult != kIOReturnSuccess) {
  102. usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
  103. @@ -554,7 +555,7 @@ static void *darwin_event_thread_main (void *arg0) {
  104. /* run the runloop */
  105. CFRunLoopRun();
  106. - usbi_dbg (ctx, "darwin event thread exiting");
  107. + usbi_dbg (NULL, "darwin event thread exiting");
  108. /* signal the main thread that the hotplug runloop has finished. */
  109. pthread_mutex_lock (&libusb_darwin_at_mutex);
  110. --
  111. 2.41.0
  112. From 2c55fbe171830b9ac28c5fbdf56cc785942d2b44 Mon Sep 17 00:00:00 2001
  113. From: Nathan Hjelm <hjelmn@google.com>
  114. Date: Wed, 6 Apr 2022 10:24:14 -0600
  115. Subject: [PATCH 3/3] darwin: Do not clear device data toggle on macOS 10.5 or
  116. newer
  117. Historically Mac OS X always cleared the data toggle on the host side. For
  118. consistency, libusb has been calling ClearPipeStallBothEnds to also clear the
  119. device side toggle. Newer versions of the IOUSBLib do not clear the host side
  120. toggle so there is no need to make this call. Additionally, some buggy devices
  121. may fail to correctly implement clearing the data toggle.
  122. Signed-off-by: Nathan Hjelm <hjelmn@google.com>
  123. [Tormod: Return result from AbortPipe]
  124. Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
  125. ---
  126. libusb/io.c | 10 +++++++---
  127. libusb/os/darwin_usb.c | 12 +++++++-----
  128. 2 files changed, 14 insertions(+), 8 deletions(-)
  129. diff --git a/libusb/io.c b/libusb/io.c
  130. index 0d2ac9ea..2a4025b1 100644
  131. --- a/libusb/io.c
  132. +++ b/libusb/io.c
  133. @@ -3,8 +3,8 @@
  134. * I/O functions for libusb
  135. * Copyright © 2007-2009 Daniel Drake <dsd@gentoo.org>
  136. * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
  137. - * Copyright © 2019 Nathan Hjelm <hjelmn@cs.umm.edu>
  138. - * Copyright © 2019 Google LLC. All rights reserved.
  139. + * Copyright © 2019-2022 Nathan Hjelm <hjelmn@cs.unm.edu>
  140. + * Copyright © 2019-2022 Google LLC. All rights reserved.
  141. *
  142. * This library is free software; you can redistribute it and/or
  143. * modify it under the terms of the GNU Lesser General Public
  144. @@ -311,7 +311,11 @@ if (r == 0 && actual_length == sizeof(data)) {
  145. * libusb_cancel_transfer() is asynchronous/non-blocking in itself. When the
  146. * cancellation actually completes, the transfer's callback function will
  147. * be invoked, and the callback function should check the transfer status to
  148. - * determine that it was cancelled.
  149. + * determine that it was cancelled. On macOS and iOS it is not possible to
  150. + * cancel a single transfer. In this case cancelling one tranfer on an endpoint
  151. + * will cause all transfers on that endpoint to be cancelled. In some cases
  152. + * the call may cause the endpoint to stall. A call to \ref libusb_clear_halt
  153. + * may be needed.
  154. *
  155. * Freeing the transfer after it has been cancelled but before cancellation
  156. * has completed will result in undefined behaviour.
  157. diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
  158. index 2c273e3a..560fe1db 100644
  159. --- a/libusb/os/darwin_usb.c
  160. +++ b/libusb/os/darwin_usb.c
  161. @@ -2238,15 +2238,17 @@ static int darwin_abort_transfers (struct usbi_transfer *itransfer) {
  162. /* abort transactions */
  163. #if InterfaceVersion >= 550
  164. if (LIBUSB_TRANSFER_TYPE_BULK_STREAM == transfer->type)
  165. - (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
  166. + kresult = (*(cInterface->interface))->AbortStreamsPipe (cInterface->interface, pipeRef, itransfer->stream_id);
  167. else
  168. #endif
  169. - (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
  170. + kresult = (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
  171. - usbi_dbg (ctx, "calling clear pipe stall to clear the data toggle bit");
  172. -
  173. - /* newer versions of darwin support clearing additional bits on the device's endpoint */
  174. +#if InterfaceVersion <= 245
  175. + /* with older releases of IOUSBFamily the OS always clears the host side data toggle. for
  176. + consistency also clear the data toggle on the device. */
  177. + usbi_dbg (ctx, "calling ClearPipeStallBothEnds to clear the data toggle bit");
  178. kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
  179. +#endif
  180. return darwin_to_libusb (kresult);
  181. }
  182. --
  183. 2.41.0
  184. From 4183a1c6c64c2266669d0ca4063845373daca6ee Mon Sep 17 00:00:00 2001
  185. From: Nathan Hjelm <hjelmn@google.com>
  186. Date: Tue, 12 Apr 2022 08:45:01 -0600
  187. Subject: [PATCH] darwin: add missing locking around cached device list cleanup
  188. The cleanup function darwin_cleanup_devices was intented to be called only once
  189. at program exit. When the initialization/finalization code was changed to
  190. destroy the cached device list on last exit this function should have been
  191. modified to require a lock on darwin_cached_devices_lock. This commit updates
  192. cleanup to protect the cached device list with the cached devices mutex and
  193. updates darwin_init to print out an error and return if a reference leak is
  194. detected.
  195. Also using this opportunity to correct the naming of the mutex. Changed
  196. darwin_cached_devices_lock to darwin_cached_devices_mutex. Also cleaning the
  197. initialization code up a bit. Removing the context pointer from the hotplug
  198. thread as it is not used for anything but logging.
  199. Fixes #1124
  200. Signed-off-by: Nathan Hjelm <hjelmn@google.com>
  201. ---
  202. libusb/os/darwin_usb.c | 139 ++++++++++++++++++++++-------------------
  203. 1 file changed, 76 insertions(+), 63 deletions(-)
  204. diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
  205. index 560fe1db..696076c7 100644
  206. --- a/libusb/os/darwin_usb.c
  207. +++ b/libusb/os/darwin_usb.c
  208. @@ -2,7 +2,7 @@
  209. /*
  210. * darwin backend for libusb 1.0
  211. * Copyright © 2008-2021 Nathan Hjelm <hjelmn@cs.unm.edu>
  212. - * Copyright © 2019-2021 Google LLC. All rights reserved.
  213. + * Copyright © 2019-2022 Google LLC. All rights reserved.
  214. *
  215. * This library is free software; you can redistribute it and/or
  216. * modify it under the terms of the GNU Lesser General Public
  217. @@ -58,6 +58,8 @@ static int init_count = 0;
  218. static const mach_port_t darwin_default_master_port = 0;
  219. /* async event thread */
  220. +/* if both this mutex and darwin_cached_devices_mutex are to be acquired then
  221. + darwin_cached_devices_mutex must be acquired first. */
  222. static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
  223. static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
  224. @@ -71,7 +73,7 @@ static clock_serv_t clock_monotonic;
  225. static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */
  226. static CFRunLoopSourceRef libusb_darwin_acfls = NULL; /* shutdown signal for event cf loop */
  227. -static usbi_mutex_t darwin_cached_devices_lock = PTHREAD_MUTEX_INITIALIZER;
  228. +static usbi_mutex_t darwin_cached_devices_mutex = PTHREAD_MUTEX_INITIALIZER;
  229. static struct list_head darwin_cached_devices;
  230. static const char *darwin_device_class = "IOUSBDevice";
  231. @@ -80,6 +82,7 @@ static const char *darwin_device_class = "IOUSBDevice";
  232. /* async event thread */
  233. static pthread_t libusb_darwin_at;
  234. +static void darwin_exit(struct libusb_context *ctx);
  235. static int darwin_get_config_descriptor(struct libusb_device *dev, uint8_t config_index, void *buffer, size_t len);
  236. static int darwin_claim_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
  237. static int darwin_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface);
  238. @@ -173,7 +176,7 @@ static enum libusb_error darwin_to_libusb (IOReturn result) {
  239. }
  240. }
  241. -/* this function must be called with the darwin_cached_devices_lock held */
  242. +/* this function must be called with the darwin_cached_devices_mutex held */
  243. static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev) {
  244. cached_dev->refcount--;
  245. /* free the device and remove it from the cache */
  246. @@ -395,7 +398,7 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
  247. /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
  248. otherwise no cached device will ever get freed */
  249. - usbi_mutex_lock(&darwin_cached_devices_lock);
  250. + usbi_mutex_lock(&darwin_cached_devices_mutex);
  251. list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
  252. if (old_device->session == session) {
  253. if (old_device->in_reenumerate) {
  254. @@ -419,7 +422,7 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
  255. }
  256. }
  257. - usbi_mutex_unlock(&darwin_cached_devices_lock);
  258. + usbi_mutex_unlock(&darwin_cached_devices_mutex);
  259. if (is_reenumerating) {
  260. continue;
  261. }
  262. @@ -467,8 +470,8 @@ static void darwin_fail_startup(void) {
  263. }
  264. static void *darwin_event_thread_main (void *arg0) {
  265. + UNUSED(arg0);
  266. IOReturn kresult;
  267. - struct libusb_context *ctx = (struct libusb_context *)arg0;
  268. CFRunLoopRef runloop;
  269. CFRunLoopSourceRef libusb_shutdown_cfsource;
  270. CFRunLoopSourceContext libusb_shutdown_cfsourcectx;
  271. @@ -496,7 +499,7 @@ static void *darwin_event_thread_main (void *arg0) {
  272. io_iterator_t libusb_add_device_iterator;
  273. /* ctx must only be used for logging during thread startup */
  274. - usbi_dbg (ctx, "creating hotplug event source");
  275. + usbi_dbg (NULL, "creating hotplug event source");
  276. runloop = CFRunLoopGetCurrent ();
  277. CFRetain (runloop);
  278. @@ -520,7 +523,7 @@ static void *darwin_event_thread_main (void *arg0) {
  279. NULL, &libusb_rem_device_iterator);
  280. if (kresult != kIOReturnSuccess) {
  281. - usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
  282. + usbi_err (NULL, "could not add hotplug event source: %s", darwin_error_str (kresult));
  283. CFRelease (libusb_shutdown_cfsource);
  284. CFRelease (runloop);
  285. darwin_fail_startup ();
  286. @@ -533,7 +536,7 @@ static void *darwin_event_thread_main (void *arg0) {
  287. NULL, &libusb_add_device_iterator);
  288. if (kresult != kIOReturnSuccess) {
  289. - usbi_err (ctx, "could not add hotplug event source: %s", darwin_error_str (kresult));
  290. + usbi_err (NULL, "could not add hotplug event source: %s", darwin_error_str (kresult));
  291. CFRelease (libusb_shutdown_cfsource);
  292. CFRelease (runloop);
  293. darwin_fail_startup ();
  294. @@ -543,7 +546,7 @@ static void *darwin_event_thread_main (void *arg0) {
  295. darwin_clear_iterator (libusb_rem_device_iterator);
  296. darwin_clear_iterator (libusb_add_device_iterator);
  297. - usbi_dbg (ctx, "darwin event thread ready to receive events");
  298. + usbi_dbg (NULL, "darwin event thread ready to receive events");
  299. /* signal the main thread that the hotplug runloop has been created. */
  300. pthread_mutex_lock (&libusb_darwin_at_mutex);
  301. @@ -583,73 +586,81 @@ static void *darwin_event_thread_main (void *arg0) {
  302. pthread_exit (NULL);
  303. }
  304. -/* cleanup function to destroy cached devices */
  305. +/* cleanup function to destroy cached devices. must be called with a lock on darwin_cached_devices_mutex */
  306. static void darwin_cleanup_devices(void) {
  307. struct darwin_cached_device *dev, *next;
  308. list_for_each_entry_safe(dev, next, &darwin_cached_devices, list, struct darwin_cached_device) {
  309. + if (dev->refcount > 1) {
  310. + usbi_err(NULL, "device still referenced at libusb_exit");
  311. + }
  312. darwin_deref_cached_device(dev);
  313. }
  314. }
  315. -static int darwin_init(struct libusb_context *ctx) {
  316. - bool first_init;
  317. - int rc;
  318. +/* must be called with a lock on darwin_cached_devices_mutex */
  319. +static int darwin_first_time_init(void) {
  320. + if (NULL == darwin_cached_devices.next) {
  321. + list_init (&darwin_cached_devices);
  322. + }
  323. - first_init = (1 == ++init_count);
  324. + if (!list_empty(&darwin_cached_devices)) {
  325. + usbi_err(NULL, "libusb_device reference not released on last exit. will not continue");
  326. + return LIBUSB_ERROR_OTHER;
  327. + }
  328. - do {
  329. - if (first_init) {
  330. - if (NULL == darwin_cached_devices.next) {
  331. - list_init (&darwin_cached_devices);
  332. - }
  333. - assert(list_empty(&darwin_cached_devices));
  334. #if !defined(HAVE_CLOCK_GETTIME)
  335. - /* create the clocks that will be used if clock_gettime() is not available */
  336. - host_name_port_t host_self;
  337. + /* create the clocks that will be used if clock_gettime() is not available */
  338. + host_name_port_t host_self;
  339. - host_self = mach_host_self();
  340. - host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
  341. - host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
  342. - mach_port_deallocate(mach_task_self(), host_self);
  343. + host_self = mach_host_self();
  344. + host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
  345. + host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
  346. + mach_port_deallocate(mach_task_self(), host_self);
  347. #endif
  348. - }
  349. - rc = darwin_scan_devices (ctx);
  350. - if (LIBUSB_SUCCESS != rc)
  351. - break;
  352. + int rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, NULL);
  353. + if (0 != rc) {
  354. + usbi_err (NULL, "could not create event thread, error %d", rc);
  355. + return LIBUSB_ERROR_OTHER;
  356. + }
  357. - if (first_init) {
  358. - rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, ctx);
  359. - if (0 != rc) {
  360. - usbi_err (ctx, "could not create event thread, error %d", rc);
  361. - rc = LIBUSB_ERROR_OTHER;
  362. - break;
  363. - }
  364. + pthread_mutex_lock (&libusb_darwin_at_mutex);
  365. + while (NULL == libusb_darwin_acfl) {
  366. + pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
  367. + }
  368. - pthread_mutex_lock (&libusb_darwin_at_mutex);
  369. - while (!libusb_darwin_acfl)
  370. - pthread_cond_wait (&libusb_darwin_at_cond, &libusb_darwin_at_mutex);
  371. - if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
  372. - libusb_darwin_acfl = NULL;
  373. - rc = LIBUSB_ERROR_OTHER;
  374. - }
  375. - pthread_mutex_unlock (&libusb_darwin_at_mutex);
  376. + if (libusb_darwin_acfl == LIBUSB_DARWIN_STARTUP_FAILURE) {
  377. + libusb_darwin_acfl = NULL;
  378. + rc = LIBUSB_ERROR_OTHER;
  379. + }
  380. + pthread_mutex_unlock (&libusb_darwin_at_mutex);
  381. +
  382. + return rc;
  383. +}
  384. +
  385. +static int darwin_init_context(struct libusb_context *ctx) {
  386. + usbi_mutex_lock(&darwin_cached_devices_mutex);
  387. - if (0 != rc)
  388. - pthread_join (libusb_darwin_at, NULL);
  389. + bool first_init = (1 == ++init_count);
  390. +
  391. + if (first_init) {
  392. + int rc = darwin_first_time_init();
  393. + if (LIBUSB_SUCCESS != rc) {
  394. + usbi_mutex_unlock(&darwin_cached_devices_mutex);
  395. + return rc;
  396. }
  397. - } while (0);
  398. + }
  399. + usbi_mutex_unlock(&darwin_cached_devices_mutex);
  400. +
  401. + return darwin_scan_devices (ctx);
  402. +}
  403. +static int darwin_init(struct libusb_context *ctx) {
  404. + int rc = darwin_init_context(ctx);
  405. if (LIBUSB_SUCCESS != rc) {
  406. - if (first_init) {
  407. - darwin_cleanup_devices ();
  408. -#if !defined(HAVE_CLOCK_GETTIME)
  409. - mach_port_deallocate(mach_task_self(), clock_realtime);
  410. - mach_port_deallocate(mach_task_self(), clock_monotonic);
  411. -#endif
  412. - }
  413. - --init_count;
  414. + /* clean up any allocated resources */
  415. + darwin_exit(ctx);
  416. }
  417. return rc;
  418. @@ -658,6 +669,7 @@ static int darwin_init(struct libusb_context *ctx) {
  419. static void darwin_exit (struct libusb_context *ctx) {
  420. UNUSED(ctx);
  421. + usbi_mutex_lock(&darwin_cached_devices_mutex);
  422. if (0 == --init_count) {
  423. /* stop the event runloop and wait for the thread to terminate. */
  424. pthread_mutex_lock (&libusb_darwin_at_mutex);
  425. @@ -675,6 +687,7 @@ static void darwin_exit (struct libusb_context *ctx) {
  426. mach_port_deallocate(mach_task_self(), clock_monotonic);
  427. #endif
  428. }
  429. + usbi_mutex_unlock(&darwin_cached_devices_mutex);
  430. }
  431. static int get_configuration_index (struct libusb_device *dev, UInt8 config_value) {
  432. @@ -1019,7 +1032,7 @@ static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io
  433. usbi_dbg(ctx, "parent sessionID: 0x%" PRIx64, parent_sessionID);
  434. }
  435. - usbi_mutex_lock(&darwin_cached_devices_lock);
  436. + usbi_mutex_lock(&darwin_cached_devices_mutex);
  437. do {
  438. list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
  439. usbi_dbg(ctx, "matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
  440. @@ -1095,7 +1108,7 @@ static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io
  441. }
  442. } while (0);
  443. - usbi_mutex_unlock(&darwin_cached_devices_lock);
  444. + usbi_mutex_unlock(&darwin_cached_devices_mutex);
  445. return ret;
  446. }
  447. @@ -1928,10 +1941,10 @@ static void darwin_destroy_device(struct libusb_device *dev) {
  448. if (dpriv->dev) {
  449. /* need to hold the lock in case this is the last reference to the device */
  450. - usbi_mutex_lock(&darwin_cached_devices_lock);
  451. + usbi_mutex_lock(&darwin_cached_devices_mutex);
  452. darwin_deref_cached_device (dpriv->dev);
  453. dpriv->dev = NULL;
  454. - usbi_mutex_unlock(&darwin_cached_devices_lock);
  455. + usbi_mutex_unlock(&darwin_cached_devices_mutex);
  456. }
  457. }
  458. @@ -2474,7 +2487,7 @@ static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
  459. struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
  460. enum libusb_error err;
  461. - usbi_mutex_lock(&darwin_cached_devices_lock);
  462. + usbi_mutex_lock(&darwin_cached_devices_mutex);
  463. (*(dpriv->device))->Release(dpriv->device);
  464. dpriv->device = darwin_device_from_service (HANDLE_CTX (dev_handle), dpriv->service);
  465. if (!dpriv->device) {
  466. @@ -2482,7 +2495,7 @@ static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
  467. } else {
  468. err = LIBUSB_SUCCESS;
  469. }
  470. - usbi_mutex_unlock(&darwin_cached_devices_lock);
  471. + usbi_mutex_unlock(&darwin_cached_devices_mutex);
  472. return err;
  473. }
  474. --
  475. 2.41.0