@@ -459,6 +459,7 @@ static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev)
459459 }
460460 IOObjectRelease (cached_dev -> service );
461461 usbi_mutex_destroy (& cached_dev -> capture_mutex );
462+ usbi_mutex_destroy (& cached_dev -> open_mutex );
462463 free (cached_dev );
463464 }
464465}
@@ -1363,6 +1364,7 @@ static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io
13631364
13641365 /* initialize locks */
13651366 usbi_mutex_init (& new_device -> capture_mutex );
1367+ usbi_mutex_init (& new_device -> open_mutex );
13661368 } else {
13671369 /* release the ref to old device's service */
13681370 IOObjectRelease (new_device -> service );
@@ -1524,7 +1526,8 @@ static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
15241526 return LIBUSB_SUCCESS ;
15251527}
15261528
1527- 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 ) {
15281531 struct darwin_device_handle_priv * priv = usbi_get_device_handle_priv (dev_handle );
15291532 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
15301533 IOReturn kresult ;
@@ -1574,7 +1577,18 @@ static int darwin_open (struct libusb_device_handle *dev_handle) {
15741577 return 0 ;
15751578}
15761579
1577- 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 ) {
15781592 struct darwin_device_handle_priv * priv = usbi_get_device_handle_priv (dev_handle );
15791593 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
15801594 IOReturn kresult ;
@@ -1618,6 +1632,14 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
16181632 }
16191633}
16201634
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+
16211643static int darwin_get_configuration (struct libusb_device_handle * dev_handle , uint8_t * config ) {
16221644 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
16231645
@@ -2016,11 +2038,15 @@ static int darwin_restore_state (struct libusb_device_handle *dev_handle, uint8_
20162038 unsigned long claimed_interfaces ) {
20172039 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
20182040 struct darwin_device_handle_priv * priv = usbi_get_device_handle_priv (dev_handle );
2019- int open_count = dpriv -> open_count ;
2041+ int open_count ;
20202042 int ret ;
20212043
20222044 struct libusb_context * ctx = HANDLE_CTX (dev_handle );
20232045
2046+ usbi_mutex_lock (& dpriv -> open_mutex );
2047+
2048+ open_count = dpriv -> open_count ;
2049+
20242050 /* clear claimed interfaces temporarily */
20252051 dev_handle -> claimed_interfaces = 0 ;
20262052
@@ -2029,11 +2055,14 @@ static int darwin_restore_state (struct libusb_device_handle *dev_handle, uint8_
20292055 dpriv -> open_count = 1 ;
20302056
20312057 /* clean up open interfaces */
2032- (void ) darwin_close (dev_handle );
2058+ (void ) _darwin_close_locked (dev_handle );
20332059
20342060 /* re-open the device */
2035- ret = darwin_open (dev_handle );
2061+ ret = _darwin_open_locked (dev_handle );
20362062 dpriv -> open_count = open_count ;
2063+
2064+ usbi_mutex_unlock (& dpriv -> open_mutex );
2065+
20372066 if (LIBUSB_SUCCESS != ret ) {
20382067 /* could not restore configuration */
20392068 return LIBUSB_ERROR_NOT_FOUND ;
0 commit comments