@@ -190,6 +190,7 @@ static void darwin_deref_cached_device(struct darwin_cached_device *cached_dev)
190190 }
191191 IOObjectRelease (cached_dev -> service );
192192 usbi_mutex_destroy (& cached_dev -> capture_mutex );
193+ usbi_mutex_destroy (& cached_dev -> open_mutex );
193194 free (cached_dev );
194195 }
195196}
@@ -1080,6 +1081,7 @@ static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io
10801081
10811082 /* initialize locks */
10821083 usbi_mutex_init (& new_device -> capture_mutex );
1084+ usbi_mutex_init (& new_device -> open_mutex );
10831085 }
10841086
10851087 /* keep track of devices regardless of if we successfully enumerate them to
@@ -1243,7 +1245,8 @@ static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) {
12431245 return LIBUSB_SUCCESS ;
12441246}
12451247
1246- static int darwin_open (struct libusb_device_handle * dev_handle ) {
1248+ /* call holding open_mutex lock */
1249+ static int _darwin_open_locked (struct libusb_device_handle * dev_handle ) {
12471250 struct darwin_device_handle_priv * priv = usbi_get_device_handle_priv (dev_handle );
12481251 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
12491252 IOReturn kresult ;
@@ -1292,7 +1295,18 @@ static int darwin_open (struct libusb_device_handle *dev_handle) {
12921295 return 0 ;
12931296}
12941297
1295- static void darwin_close (struct libusb_device_handle * dev_handle ) {
1298+ static int darwin_open (struct libusb_device_handle * dev_handle ) {
1299+ struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
1300+ enum libusb_error ret ;
1301+
1302+ usbi_mutex_lock (& dpriv -> open_mutex );
1303+ ret = _darwin_open_locked (dev_handle );
1304+ usbi_mutex_unlock (& dpriv -> open_mutex );
1305+ return ret ;
1306+ }
1307+
1308+ /* call holding open_mutex lock */
1309+ static void _darwin_close_locked (struct libusb_device_handle * dev_handle ) {
12961310 struct darwin_device_handle_priv * priv = usbi_get_device_handle_priv (dev_handle );
12971311 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
12981312 IOReturn kresult ;
@@ -1336,6 +1350,14 @@ static void darwin_close (struct libusb_device_handle *dev_handle) {
13361350 }
13371351}
13381352
1353+ static void darwin_close (struct libusb_device_handle * dev_handle ) {
1354+ struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
1355+
1356+ usbi_mutex_lock (& dpriv -> open_mutex );
1357+ _darwin_close_locked (dev_handle );
1358+ usbi_mutex_unlock (& dpriv -> open_mutex );
1359+ }
1360+
13391361static int darwin_get_configuration (struct libusb_device_handle * dev_handle , uint8_t * config ) {
13401362 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
13411363
@@ -1710,11 +1732,15 @@ static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t
17101732 unsigned long claimed_interfaces ) {
17111733 struct darwin_cached_device * dpriv = DARWIN_CACHED_DEVICE (dev_handle -> dev );
17121734 struct darwin_device_handle_priv * priv = usbi_get_device_handle_priv (dev_handle );
1713- int open_count = dpriv -> open_count ;
1735+ int open_count ;
17141736 int ret ;
17151737
17161738 struct libusb_context * ctx = HANDLE_CTX (dev_handle );
17171739
1740+ usbi_mutex_lock (& dpriv -> open_mutex );
1741+
1742+ open_count = dpriv -> open_count ;
1743+
17181744 /* clear claimed interfaces temporarily */
17191745 dev_handle -> claimed_interfaces = 0 ;
17201746
@@ -1723,11 +1749,14 @@ static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t
17231749 dpriv -> open_count = 1 ;
17241750
17251751 /* clean up open interfaces */
1726- (void ) darwin_close (dev_handle );
1752+ (void ) _darwin_close_locked (dev_handle );
17271753
17281754 /* re-open the device */
1729- ret = darwin_open (dev_handle );
1755+ ret = _darwin_open_locked (dev_handle );
17301756 dpriv -> open_count = open_count ;
1757+
1758+ usbi_mutex_unlock (& dpriv -> open_mutex );
1759+
17311760 if (LIBUSB_SUCCESS != ret ) {
17321761 /* could not restore configuration */
17331762 return LIBUSB_ERROR_NOT_FOUND ;
0 commit comments