@@ -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,7 @@ 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 );
460462 free (cached_dev );
461463 }
462464}
@@ -1358,6 +1360,9 @@ static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io
13581360 (* device )-> GetLocationID (device , & new_device -> location );
13591361 new_device -> port = port ;
13601362 new_device -> parent_session = parent_sessionID ;
1363+
1364+ /* initialize locks */
1365+ usbi_mutex_init (& new_device -> capture_mutex );
13611366 } else {
13621367 /* release the ref to old device's service */
13631368 IOObjectRelease (new_device -> service );
@@ -2069,6 +2074,7 @@ static int darwin_restore_state (struct libusb_device_handle *dev_handle, uint8_
20692074 return LIBUSB_SUCCESS ;
20702075}
20712076
2077+ /* call holding capture_mutex lock */
20722078static int darwin_reenumerate_device (struct libusb_device_handle * dev_handle , bool capture ) {
20732079 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
20742080 unsigned long claimed_interfaces = dev_handle -> claimed_interfaces ;
@@ -2168,7 +2174,8 @@ static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, b
21682174 return darwin_restore_state (dev_handle , active_config , claimed_interfaces );
21692175}
21702176
2171- static int darwin_reset_device (struct libusb_device_handle * dev_handle ) {
2177+ /* call holding capture_mutex lock */
2178+ static int _darwin_reset_device_locked (struct libusb_device_handle * dev_handle ) {
21722179 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
21732180 IOReturn kresult ;
21742181 enum libusb_error ret ;
@@ -2194,7 +2201,7 @@ static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
21942201 /* reset capture count */
21952202 dpriv -> capture_count = 0 ;
21962203 /* attempt to detach kernel driver again as it is now re-attached */
2197- ret = darwin_detach_kernel_driver (dev_handle , 0 );
2204+ ret = _darwin_detach_kernel_driver_locked (dev_handle , 0 );
21982205 if (ret != LIBUSB_SUCCESS ) {
21992206 return ret ;
22002207 }
@@ -2207,6 +2214,16 @@ static int darwin_reset_device (struct libusb_device_handle *dev_handle) {
22072214 return ret ;
22082215}
22092216
2217+ static int darwin_reset_device (struct libusb_device_handle * dev_handle ) {
2218+ struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
2219+ enum libusb_error ret ;
2220+
2221+ usbi_mutex_lock (& dpriv -> capture_mutex );
2222+ ret = _darwin_reset_device_locked (dev_handle );
2223+ usbi_mutex_unlock (& dpriv -> capture_mutex );
2224+ return ret ;
2225+ }
2226+
22102227static io_service_t usb_find_interface_matching_location (const io_name_t class_name , UInt8 interface_number , UInt32 location ) {
22112228 CFMutableDictionaryRef matchingDict = IOServiceMatching (class_name );
22122229 CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable (kCFAllocatorDefault , 0 ,
@@ -2822,7 +2839,8 @@ static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
28222839
28232840/* On macOS, we capture an entire device at once, not individual interfaces. */
28242841
2825- static int darwin_detach_kernel_driver (struct libusb_device_handle * dev_handle , uint8_t interface ) {
2842+ /* call holding capture_mutex lock */
2843+ static int _darwin_detach_kernel_driver_locked (struct libusb_device_handle * dev_handle , uint8_t interface ) {
28262844 UNUSED (interface );
28272845 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
28282846 IOReturn kresult ;
@@ -2867,8 +2885,18 @@ static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle,
28672885 return LIBUSB_SUCCESS ;
28682886}
28692887
2888+ static int darwin_detach_kernel_driver (struct libusb_device_handle * dev_handle , uint8_t interface ) {
2889+ struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
2890+ enum libusb_error ret ;
28702891
2871- static int darwin_attach_kernel_driver (struct libusb_device_handle * dev_handle , uint8_t interface ) {
2892+ usbi_mutex_lock (& dpriv -> capture_mutex );
2893+ ret = _darwin_detach_kernel_driver_locked (dev_handle , interface );
2894+ usbi_mutex_unlock (& dpriv -> capture_mutex );
2895+ return ret ;
2896+ }
2897+
2898+ /* call holding capture_mutex lock */
2899+ static int _darwin_attach_kernel_driver_locked (struct libusb_device_handle * dev_handle , uint8_t interface ) {
28722900 UNUSED (interface );
28732901 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
28742902
@@ -2887,6 +2915,16 @@ static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle,
28872915 return darwin_reenumerate_device (dev_handle , false);
28882916}
28892917
2918+ static int darwin_attach_kernel_driver (struct libusb_device_handle * dev_handle , uint8_t interface ) {
2919+ struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
2920+ enum libusb_error ret ;
2921+
2922+ usbi_mutex_lock (& dpriv -> capture_mutex );
2923+ ret = _darwin_attach_kernel_driver_locked (dev_handle , interface );
2924+ usbi_mutex_unlock (& dpriv -> capture_mutex );
2925+ return ret ;
2926+ }
2927+
28902928static int darwin_capture_claim_interface (struct libusb_device_handle * dev_handle , uint8_t iface ) {
28912929 enum libusb_error ret ;
28922930 if (dev_handle -> auto_detach_kernel_driver && darwin_kernel_driver_active (dev_handle , iface )) {
@@ -2899,7 +2937,8 @@ static int darwin_capture_claim_interface(struct libusb_device_handle *dev_handl
28992937 return darwin_claim_interface (dev_handle , iface );
29002938}
29012939
2902- static int darwin_capture_release_interface (struct libusb_device_handle * dev_handle , uint8_t iface ) {
2940+ /* call holding capture_mutex lock */
2941+ static int _darwin_capture_release_interface_locked (struct libusb_device_handle * dev_handle , uint8_t iface ) {
29032942 enum libusb_error ret ;
29042943 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
29052944
@@ -2909,7 +2948,7 @@ static int darwin_capture_release_interface(struct libusb_device_handle *dev_han
29092948 }
29102949
29112950 if (dev_handle -> auto_detach_kernel_driver && dpriv -> capture_count > 0 ) {
2912- ret = darwin_attach_kernel_driver (dev_handle , iface );
2951+ ret = _darwin_attach_kernel_driver_locked (dev_handle , iface );
29132952 if (LIBUSB_SUCCESS != ret ) {
29142953 usbi_info (HANDLE_CTX (dev_handle ), "on attempt to reattach the kernel driver got ret=%d" , ret );
29152954 }
@@ -2919,6 +2958,16 @@ static int darwin_capture_release_interface(struct libusb_device_handle *dev_han
29192958 return LIBUSB_SUCCESS ;
29202959}
29212960
2961+ static int darwin_capture_release_interface (struct libusb_device_handle * dev_handle , uint8_t iface ) {
2962+ struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
2963+ enum libusb_error ret ;
2964+
2965+ usbi_mutex_lock (& dpriv -> capture_mutex );
2966+ ret = _darwin_capture_release_interface_locked (dev_handle , iface );
2967+ usbi_mutex_unlock (& dpriv -> capture_mutex );
2968+ return ret ;
2969+ }
2970+
29222971#endif
29232972
29242973const struct usbi_os_backend usbi_backend = {
0 commit comments