Skip to content

Commit ae2002c

Browse files
committed
Unplug test
1 parent 547950d commit ae2002c

File tree

8 files changed

+362
-9
lines changed

8 files changed

+362
-9
lines changed

java-does-usb/jextract/macos/gen_macos.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ $JEXTRACT --source --output ../../src/main/java \
3939
--include-constant kIOUSBDeviceClassName \
4040
--include-constant kIOFirstMatchNotification \
4141
--include-constant kIOTerminatedNotification \
42+
--include-constant kIOReturnExclusiveAccess \
4243
--include-var kCFRunLoopDefaultMode \
4344
--include-struct IOCFPlugInInterfaceStruct \
4445
--include-typedef IOCFPlugInInterface \

java-does-usb/src/main/java/net/codecrete/usb/macos/MacosUSBDevice.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@ public class MacosUSBDevice extends USBDeviceImpl {
5555
// Details about endpoints of current alternate settings (for claimed interfaces)
5656
private Map<Byte, EndpointInfo> endpoints;
5757

58+
private final long discoveryTime;
59+
5860
MacosUSBDevice(MemorySegment device, Object id, int vendorId, int productId) {
5961
super(id, vendorId, productId);
62+
discoveryTime = System.currentTimeMillis();
6063
asyncTask = MacosAsyncTask.instance();
6164

6265
loadDescription(device);
@@ -75,13 +78,27 @@ public synchronized void open() {
7578
if (isOpen())
7679
throwException("the device is already open");
7780

78-
// open device
79-
int ret = IoKitUSB.USBDeviceOpenSeize(device);
81+
// open device (several retries if device has just been connected/discovered)
82+
long duration = System.currentTimeMillis() - discoveryTime;
83+
int numTries = duration < 1000 ? 4 : 1;
84+
int ret = 0;
85+
while (numTries > 0) {
86+
numTries -= 1;
87+
ret = IoKitUSB.USBDeviceOpenSeize(device);
88+
if (ret != IOKit.kIOReturnExclusiveAccess())
89+
break;
90+
91+
// sleep and retry
92+
try {
93+
Thread.sleep(90);
94+
} catch (InterruptedException e) {
95+
// ignore
96+
}
97+
}
8098
if (ret != 0)
8199
throwException(ret, "unable to open USB device");
82100

83101
claimedInterfaces = new ArrayList<>();
84-
85102
addDeviceEventSource();
86103

87104
// set configuration
@@ -541,15 +558,15 @@ public void clearHalt(USBDirection direction, int endpointNumber) {
541558
}
542559

543560
@Override
544-
public InputStream openInputStream(int endpointNumber, int bufferSize) {
561+
public synchronized InputStream openInputStream(int endpointNumber, int bufferSize) {
545562
// check that endpoint number is valid
546563
getEndpointInfo(endpointNumber, USBDirection.IN, USBTransferType.BULK, null);
547564

548565
return new MacosEndpointInputStream(this, endpointNumber, bufferSize);
549566
}
550567

551568
@Override
552-
public OutputStream openOutputStream(int endpointNumber, int bufferSize) {
569+
public synchronized OutputStream openOutputStream(int endpointNumber, int bufferSize) {
553570
// check that endpoint number is valid
554571
getEndpointInfo(endpointNumber, USBDirection.OUT, USBTransferType.BULK, null);
555572

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/iokit/IOKit.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,14 @@ public static int IOCreatePlugInInterfaceForService(int service, MemorySegment p
224224
throw new AssertionError("should not reach here", ex$);
225225
}
226226
}
227+
/**
228+
* {@snippet :
229+
* #define kIOReturnExclusiveAccess -536870203
230+
* }
231+
*/
232+
public static int kIOReturnExclusiveAccess() {
233+
return (int)-536870203L;
234+
}
227235
/**
228236
* {@snippet :
229237
* #define kIOReturnAborted -536870165

java-does-usb/src/test/java/net/codecrete/usb/sample/EnumerateDevices.java renamed to java-does-usb/src/test/java/net/codecrete/usb/special/EnumerateDevices.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// https://opensource.org/licenses/MIT
66
//
77

8-
package net.codecrete.usb.sample;
8+
package net.codecrete.usb.special;
99

1010
import net.codecrete.usb.USB;
1111

java-does-usb/src/test/java/net/codecrete/usb/sample/LogicAnalyzer.java renamed to java-does-usb/src/test/java/net/codecrete/usb/special/LogicAnalyzer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// and licensed under GNU GPL (version 2, or later).
99
//
1010

11-
package net.codecrete.usb.sample;
11+
package net.codecrete.usb.special;
1212

1313
import net.codecrete.usb.*;
1414

java-does-usb/src/test/java/net/codecrete/usb/sample/MonitorDevices.java renamed to java-does-usb/src/test/java/net/codecrete/usb/special/MonitorDevices.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// https://opensource.org/licenses/MIT
66
//
77

8-
package net.codecrete.usb.sample;
8+
package net.codecrete.usb.special;
99

1010
import net.codecrete.usb.USB;
1111

java-does-usb/src/test/java/net/codecrete/usb/sample/USBSerialTest.java renamed to java-does-usb/src/test/java/net/codecrete/usb/special/USBSerialTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// https://opensource.org/licenses/MIT
66
//
77

8-
package net.codecrete.usb.sample;
8+
package net.codecrete.usb.special;
99

1010
import net.codecrete.usb.*;
1111

0 commit comments

Comments
 (0)