@@ -90,6 +90,7 @@ static int darwin_reenumerate_device(struct libusb_device_handle *dev_handle, bo
9090static int darwin_clear_halt (struct libusb_device_handle * dev_handle , unsigned char endpoint );
9191static int darwin_reset_device (struct libusb_device_handle * dev_handle );
9292static int darwin_detach_kernel_driver (struct libusb_device_handle * dev_handle , uint8_t interface );
93+ static int _darwin_detach_kernel_driver_locked (struct libusb_device_handle * dev_handle , uint8_t interface );
9394static void darwin_async_io_callback (void * refcon , IOReturn result , void * arg0 );
9495
9596static enum libusb_error darwin_scan_devices (struct libusb_context * ctx );
@@ -457,6 +458,8 @@ static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev)
457458 cached_dev -> device = NULL ;
458459 }
459460 IOObjectRelease (cached_dev -> service );
461+ usbi_mutex_destroy (& cached_dev -> capture_mutex );
462+ usbi_mutex_destroy (& cached_dev -> open_mutex );
460463 free (cached_dev );
461464 }
462465}
@@ -1358,6 +1361,10 @@ static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io
13581361 (* device )-> GetLocationID (device , & new_device -> location );
13591362 new_device -> port = port ;
13601363 new_device -> parent_session = parent_sessionID ;
1364+
1365+ /* initialize locks */
1366+ usbi_mutex_init (& new_device -> capture_mutex );
1367+ usbi_mutex_init (& new_device -> open_mutex );
13611368 } else {
13621369 /* release the ref to old device's service */
13631370 IOObjectRelease (new_device -> service );
@@ -1519,7 +1526,8 @@ static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
15191526 return LIBUSB_SUCCESS ;
15201527}
15211528
1522- static int darwin_open (struct libusb_device_handle * dev_handle ) {
1529+ /* call holding open_mutex lock */
1530+ static int _darwin_open_locked (struct libusb_device_handle * dev_handle ) {
15231531 struct darwin_device_handle_priv * priv = usbi_get_device_handle_priv (dev_handle );
15241532 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
15251533 IOReturn kresult ;
@@ -1569,7 +1577,18 @@ static int darwin_open (struct libusb_device_handle *dev_handle) {
15691577 return 0 ;
15701578}
15711579
1572- static void darwin_close (struct libusb_device_handle * dev_handle ) {
1580+ static int darwin_open (struct libusb_device_handle * dev_handle ) {
1581+ struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
1582+ enum libusb_error ret ;
1583+
1584+ usbi_mutex_lock (& dpriv -> open_mutex );
1585+ ret = _darwin_open_locked (dev_handle );
1586+ usbi_mutex_unlock (& dpriv -> open_mutex );
1587+ return ret ;
1588+ }
1589+
1590+ /* call holding open_mutex lock */
1591+ static void _darwin_close_locked (struct libusb_device_handle * dev_handle ) {
15731592 struct darwin_device_handle_priv * priv = usbi_get_device_handle_priv (dev_handle );
15741593 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
15751594 IOReturn kresult ;
@@ -1613,6 +1632,14 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
16131632 }
16141633}
16151634
1635+ static void darwin_close (struct libusb_device_handle * dev_handle ) {
1636+ struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
1637+
1638+ usbi_mutex_lock (& dpriv -> open_mutex );
1639+ _darwin_close_locked (dev_handle );
1640+ usbi_mutex_unlock (& dpriv -> open_mutex );
1641+ }
1642+
16161643static int darwin_get_configuration (struct libusb_device_handle * dev_handle , uint8_t * config ) {
16171644 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
16181645
@@ -2011,11 +2038,15 @@ static int darwin_restore_state (struct libusb_device_handle *dev_handle, uint8_
20112038 unsigned long claimed_interfaces ) {
20122039 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
20132040 struct darwin_device_handle_priv * priv = usbi_get_device_handle_priv (dev_handle );
2014- int open_count = dpriv -> open_count ;
2041+ int open_count ;
20152042 int ret ;
20162043
20172044 struct libusb_context * ctx = HANDLE_CTX (dev_handle );
20182045
2046+ usbi_mutex_lock (& dpriv -> open_mutex );
2047+
2048+ open_count = dpriv -> open_count ;
2049+
20192050 /* clear claimed interfaces temporarily */
20202051 dev_handle -> claimed_interfaces = 0 ;
20212052
@@ -2024,11 +2055,14 @@ static int darwin_restore_state (struct libusb_device_handle *dev_handle, uint8_
20242055 dpriv -> open_count = 1 ;
20252056
20262057 /* clean up open interfaces */
2027- (void ) darwin_close (dev_handle );
2058+ (void ) _darwin_close_locked (dev_handle );
20282059
20292060 /* re-open the device */
2030- ret = darwin_open (dev_handle );
2061+ ret = _darwin_open_locked (dev_handle );
20312062 dpriv -> open_count = open_count ;
2063+
2064+ usbi_mutex_unlock (& dpriv -> open_mutex );
2065+
20322066 if (LIBUSB_SUCCESS != ret ) {
20332067 /* could not restore configuration */
20342068 return LIBUSB_ERROR_NOT_FOUND ;
@@ -2069,6 +2103,7 @@ static int darwin_restore_state (struct libusb_device_handle *dev_handle, uint8_
20692103 return LIBUSB_SUCCESS ;
20702104}
20712105
2106+ /* call holding capture_mutex lock */
20722107static int darwin_reenumerate_device (struct libusb_device_handle * dev_handle , bool capture ) {
20732108 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
20742109 unsigned long claimed_interfaces = dev_handle -> claimed_interfaces ;
@@ -2168,7 +2203,8 @@ static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, b
21682203 return darwin_restore_state (dev_handle , active_config , claimed_interfaces );
21692204}
21702205
2171- static int darwin_reset_device (struct libusb_device_handle * dev_handle ) {
2206+ /* call holding capture_mutex lock */
2207+ static int _darwin_reset_device_locked (struct libusb_device_handle * dev_handle ) {
21722208 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
21732209 IOReturn kresult ;
21742210 enum libusb_error ret ;
@@ -2194,7 +2230,7 @@ static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
21942230 /* reset capture count */
21952231 dpriv -> capture_count = 0 ;
21962232 /* attempt to detach kernel driver again as it is now re-attached */
2197- ret = darwin_detach_kernel_driver (dev_handle , 0 );
2233+ ret = _darwin_detach_kernel_driver_locked (dev_handle , 0 );
21982234 if (ret != LIBUSB_SUCCESS ) {
21992235 return ret ;
22002236 }
@@ -2207,6 +2243,16 @@ static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
22072243 return ret ;
22082244}
22092245
2246+ static int darwin_reset_device (struct libusb_device_handle * dev_handle ) {
2247+ struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
2248+ enum libusb_error ret ;
2249+
2250+ usbi_mutex_lock (& dpriv -> capture_mutex );
2251+ ret = _darwin_reset_device_locked (dev_handle );
2252+ usbi_mutex_unlock (& dpriv -> capture_mutex );
2253+ return ret ;
2254+ }
2255+
22102256static io_service_t usb_find_interface_matching_location (const io_name_t class_name , UInt8 interface_number , UInt32 location ) {
22112257 CFMutableDictionaryRef matchingDict = IOServiceMatching (class_name );
22122258 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable (kCFAllocatorDefault , 0 ,
@@ -2822,7 +2868,8 @@ static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
28222868
28232869/* On macOS, we capture an entire device at once, not individual interfaces. */
28242870
2825- static int darwin_detach_kernel_driver (struct libusb_device_handle * dev_handle , uint8_t interface ) {
2871+ /* call holding capture_mutex lock */
2872+ static int _darwin_detach_kernel_driver_locked (struct libusb_device_handle * dev_handle , uint8_t interface ) {
28262873 UNUSED (interface );
28272874 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
28282875 IOReturn kresult ;
@@ -2867,8 +2914,18 @@ static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle,
28672914 return LIBUSB_SUCCESS ;
28682915}
28692916
2917+ static int darwin_detach_kernel_driver (struct libusb_device_handle * dev_handle , uint8_t interface ) {
2918+ struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
2919+ enum libusb_error ret ;
2920+
2921+ usbi_mutex_lock (& dpriv -> capture_mutex );
2922+ ret = _darwin_detach_kernel_driver_locked (dev_handle , interface );
2923+ usbi_mutex_unlock (& dpriv -> capture_mutex );
2924+ return ret ;
2925+ }
28702926
2871- static int darwin_attach_kernel_driver (struct libusb_device_handle * dev_handle , uint8_t interface ) {
2927+ /* call holding capture_mutex lock */
2928+ static int _darwin_attach_kernel_driver_locked (struct libusb_device_handle * dev_handle , uint8_t interface ) {
28722929 UNUSED (interface );
28732930 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
28742931
@@ -2887,6 +2944,16 @@ static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle,
28872944 return darwin_reenumerate_device (dev_handle , false);
28882945}
28892946
2947+ static int darwin_attach_kernel_driver (struct libusb_device_handle * dev_handle , uint8_t interface ) {
2948+ struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
2949+ enum libusb_error ret ;
2950+
2951+ usbi_mutex_lock (& dpriv -> capture_mutex );
2952+ ret = _darwin_attach_kernel_driver_locked (dev_handle , interface );
2953+ usbi_mutex_unlock (& dpriv -> capture_mutex );
2954+ return ret ;
2955+ }
2956+
28902957static int darwin_capture_claim_interface (struct libusb_device_handle * dev_handle , uint8_t iface ) {
28912958 enum libusb_error ret ;
28922959 if (dev_handle -> auto_detach_kernel_driver && darwin_kernel_driver_active (dev_handle , iface )) {
@@ -2899,7 +2966,8 @@ static int darwin_capture_claim_interface(struct libusb_device_handle *dev_handl
28992966 return darwin_claim_interface (dev_handle , iface );
29002967}
29012968
2902- static int darwin_capture_release_interface (struct libusb_device_handle * dev_handle , uint8_t iface ) {
2969+ /* call holding capture_mutex lock */
2970+ static int _darwin_capture_release_interface_locked (struct libusb_device_handle * dev_handle , uint8_t iface ) {
29032971 enum libusb_error ret ;
29042972 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
29052973
@@ -2909,7 +2977,7 @@ static int darwin_capture_release_interface(struct libusb_device_handle *dev_han
29092977 }
29102978
29112979 if (dev_handle -> auto_detach_kernel_driver && dpriv -> capture_count > 0 ) {
2912- ret = darwin_attach_kernel_driver (dev_handle , iface );
2980+ ret = _darwin_attach_kernel_driver_locked (dev_handle , iface );
29132981 if (LIBUSB_SUCCESS != ret ) {
29142982 usbi_info (HANDLE_CTX (dev_handle ), "on attempt to reattach the kernel driver got ret=%d" , ret );
29152983 }
@@ -2919,6 +2987,16 @@ static int darwin_capture_release_interface(struct libusb_device_handle *dev_han
29192987 return LIBUSB_SUCCESS ;
29202988}
29212989
2990+ static int darwin_capture_release_interface (struct libusb_device_handle * dev_handle , uint8_t iface ) {
2991+ struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
2992+ enum libusb_error ret ;
2993+
2994+ usbi_mutex_lock (& dpriv -> capture_mutex );
2995+ ret = _darwin_capture_release_interface_locked (dev_handle , iface );
2996+ usbi_mutex_unlock (& dpriv -> capture_mutex );
2997+ return ret ;
2998+ }
2999+
29223000#endif
29233001
29243002const struct usbi_os_backend usbi_backend = {
0 commit comments