Skip to content

Commit c8c49a6

Browse files
committed
Linux: check that device has not been disconnected
1 parent e019f50 commit c8c49a6

File tree

6 files changed

+25
-34
lines changed

6 files changed

+25
-34
lines changed

java-does-usb/src/main/java/net/codecrete/usb/common/UsbDeviceImpl.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ protected void checkIsOpen() {
9595
throw new UsbException("device needs to be opened first for this operation");
9696
}
9797

98+
protected void checkIsClosed(String message) {
99+
if (!connected)
100+
throw new UsbException("device has been disconnected");
101+
if (isOpened())
102+
throw new UsbException(message);
103+
}
104+
105+
protected synchronized void disconnect() {
106+
connected = false;
107+
close();
108+
}
109+
98110
@Override
99111
public int getProductId() {
100112
return pid;

java-does-usb/src/main/java/net/codecrete/usb/common/UsbDeviceRegistry.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ protected void closeAndRemoveDevice(Object deviceId) {
204204
return;
205205

206206
try {
207-
device.close();
207+
((UsbDeviceImpl)device).disconnect();
208208
} catch (Exception e) {
209-
LOG.log(INFO, "failed to close USB device - ignoring exception", e);
209+
LOG.log(INFO, "failed to close disconnected USB device - ignoring exception", e);
210210
}
211211

212212
removeDevice(deviceId);

java-does-usb/src/main/java/net/codecrete/usb/linux/LinuxUsbDevice.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,14 @@ private void loadDescription(String path) {
7171
}
7272

7373
@Override
74-
public void detachStandardDrivers() {
75-
if (isOpened())
76-
throwException("detachStandardDrivers() must not be called while the device is open");
74+
public synchronized void detachStandardDrivers() {
75+
checkIsClosed("detachStandardDrivers() must not be called while the device is open");
7776
detachDrivers = true;
7877
}
7978

8079
@Override
81-
public void attachStandardDrivers() {
82-
if (isOpened())
83-
throwException("attachStandardDrivers() must not be called while the device is open");
80+
public synchronized void attachStandardDrivers() {
81+
checkIsClosed("attachStandardDrivers() must not be called while the device is open");
8482
detachDrivers = false;
8583
}
8684

@@ -91,8 +89,7 @@ public boolean isOpened() {
9189

9290
@Override
9391
public synchronized void open() {
94-
if (isOpened())
95-
throwException("device is already open");
92+
checkIsClosed("device is already open");
9693

9794
try (var arena = Arena.ofConfined()) {
9895
var pathUtf8 = arena.allocateFrom(uniqueDeviceId.toString());

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

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,6 @@ public boolean isOpened() {
9898
return claimedInterfaces != null;
9999
}
100100

101-
private void checkIsClosed(String message) {
102-
if (!connected)
103-
throwException("device has been disconnected");
104-
if (isOpened())
105-
throwException(message);
106-
}
107-
108101
@SuppressWarnings("java:S2276")
109102
@Override
110103
public synchronized void open() {
@@ -164,9 +157,9 @@ public synchronized void close() {
164157
asyncTask.removeEventSource(source);
165158
}
166159

167-
synchronized void closeFully() {
168-
connected = false;
169-
close();
160+
@Override
161+
protected synchronized void disconnect() {
162+
super.disconnect();
170163
IoKitUsb.Release(device);
171164
device = null;
172165
}

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

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -267,19 +267,7 @@ private void onDevicesConnected(MemorySegment ignoredRefCon, int iterator) {
267267
private void onDevicesDisconnected(MemorySegment ignoredRefCon, int iterator) {
268268

269269
// process device iterator for disconnected devices
270-
iterateDevices(iterator, (entryId, _, _) -> {
271-
var device = findDevice(entryId);
272-
if (device == null)
273-
return;
274-
275-
try {
276-
((MacosUsbDevice) device).closeFully();
277-
} catch (Exception e) {
278-
LOG.log(INFO, "failed to close USB device - ignoring exception", e);
279-
}
280-
281-
removeDevice(entryId);
282-
});
270+
iterateDevices(iterator, (entryId, _, _) -> closeAndRemoveDevice(entryId));
283271
}
284272

285273
@FunctionalInterface

java-does-usb/src/test/java/net/codecrete/usb/special/Unplug.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ private static void onUnpluggedDevice(UsbDevice device) {
6565
device.open();
6666
System.err.println("Device should not be openable after disconnect");
6767
} catch (UsbException e) {
68-
// expected
68+
if (!e.getMessage().contains("disconnected"))
69+
System.err.println(STR."Unexpected error: \{e.getMessage()}");
6970
}
7071
}).start();
7172
}

0 commit comments

Comments
 (0)