Skip to content

Commit

Permalink
fix #1 use static reference instead of instant reference
Browse files Browse the repository at this point in the history
  • Loading branch information
umjammer committed Oct 18, 2023
1 parent 7ffdd3d commit 3aa8a93
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 37 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@

<dependencies>
<dependency>
<groupId>com.github.umjammer.jinput</groupId>
<groupId>com.github.umjammer.jinput</groupId> <!-- net.java.jinput / com.github.umjammer.jinput -->
<artifactId>osx-plugin</artifactId>
<version>2.0.11v</version>
</dependency>
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/org/hid4java/macos/MacosHidDevice.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

import static org.hid4java.HidDevice.logTraffic;
import static vavix.rococoa.corefoundation.CFLib.kCFRunLoopDefaultMode;
import static vavix.rococoa.iokit.IOKitLib.kIOHIDOptionsTypeSeizeDevice;
import static vavix.rococoa.iokit.IOKitLib.kIOHIDReportTypeFeature;
import static vavix.rococoa.iokit.IOKitLib.kIOHIDReportTypeInput;
import static vavix.rococoa.iokit.IOKitLib.kIOReturnSuccess;
Expand Down Expand Up @@ -129,6 +130,7 @@ public void close() {
// Notify the read thread that it can shut down now.
logger.finer("here20.4: " + Thread.currentThread() + ", " + this.thread);
if (Thread.currentThread() != this.thread) {
this.thread.interrupt();
logger.finest("here20.5: notify shutdownBarrier -1");
this.shutdownBarrier.waitAndSync();

Expand All @@ -151,7 +153,7 @@ public void close() {
// Not leaking a resource in all tested environments.

if (MacosHidDeviceManager.is_macos_10_10_or_greater || !this.disconnected) {
IOKitLib.INSTANCE.IOHIDDeviceClose(this.deviceHandle.device, this.openOptions);
IOKitLib.INSTANCE.IOHIDDeviceClose(this.deviceHandle.device, kIOHIDOptionsTypeSeizeDevice);
logger.finer("here20.7: native device close: @" + this.deviceHandle.device.hashCode());
}

Expand Down
66 changes: 31 additions & 35 deletions src/main/java/org/hid4java/macos/MacosHidDeviceManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.sun.jna.Memory;
Expand Down Expand Up @@ -215,8 +216,8 @@ public List<HidDevice.Info> enumerate(int vendorId, int productId) throws IOExce
}
logger.finest("here7.0: " + matching + ", " + Thread.currentThread());
IOKitLib.INSTANCE.IOHIDManagerSetDeviceMatching(manager, matching);
logger.finest("here7.1");
if (matching != null) {
logger.finer("here7.1: matching null");
CFLib.INSTANCE.CFRelease(matching);
}

Expand Down Expand Up @@ -292,13 +293,13 @@ public List<HidDevice.Info> enumerate(int vendorId, int productId) throws IOExce
}

/** Stop the Run Loop for this device */
private void onDeviceRemovalCallback(Pointer context, int /* IOReturn */ result, Pointer sender) {
private static void onDeviceRemovalCallback(Pointer context, int /* IOReturn */ result, Pointer sender) {
MacosHidDevice dev = (MacosHidDevice) UserObjectContext.getObjectFromContext(context);
if (dev == null) {
logger.fine("here5.0: dev is null");
logger.fine("here5.1: dev is null");
return;
}
logger.fine("here5: device_removal_callback: dev: " + dev.deviceInfo.product);
logger.fine("here5.2: device_removal_callback: dev: " + dev.deviceInfo.product);

dev.disconnected = true;
dev.close();
Expand All @@ -308,16 +309,16 @@ private void onDeviceRemovalCallback(Pointer context, int /* IOReturn */ result,
* This gets called when the read_thread's run loop gets signaled by
* {@link MacosHidDevice#close()}, and serves to stop the read_thread's run loop.
*/
private void onSignalCallback(Pointer context) {
private static void onSignalCallback(Pointer context) {
MacosHidDevice dev = (MacosHidDevice) UserObjectContext.getObjectFromContext(context);
if (dev == null) {
logger.fine("here3.0: dev is null");
logger.fine("here3.1: dev is null");
return;
}
logger.fine("here3.1: signal_callback: dev: " + dev.deviceInfo.product);
logger.fine("here3.2: signal_callback: dev: " + dev.deviceInfo.product);

CFLib.INSTANCE.CFRunLoopStop(dev.runLoop); // TODO CFRunLoopGetCurrent()
logger.finest("here3.2: stop run loop: @" + dev.runLoop.hashCode());
logger.finest("here3.3: stop run loop: @" + dev.runLoop.hashCode());
}

/**
Expand All @@ -327,13 +328,13 @@ private void onSignalCallback(Pointer context) {
*
* @see IOKitLib.IOHIDReportCallback
*/
private void onReportCallback(Pointer context, int/*IOReturn*/ result, Pointer sender, int/*IOHIDReportType*/ report_type, int report_id, Pointer report, CFIndex reportLength) {
private static void onReportCallback(Pointer context, int/*IOReturn*/ result, Pointer sender, int/*IOHIDReportType*/ report_type, int report_id, Pointer report, CFIndex reportLength) {
MacosHidDevice dev = (MacosHidDevice) UserObjectContext.getObjectFromContext(context);
if (dev == null) {
logger.fine("here4.0: dev is null: " + UserObjectContext.objectIDMaster);
logger.fine("here4.1: dev is null: " + UserObjectContext.objectIDMaster);
return;
}
logger.finest("here4: report_callback: dev: " + dev.deviceInfo.product);
logger.finest("here4.2: report_callback: dev: " + dev.deviceInfo.product);

// Make a new Input Report object
int length = reportLength.intValue();
Expand All @@ -342,7 +343,7 @@ private void onReportCallback(Pointer context, int/*IOReturn*/ result, Pointer s
// Signal a waiting thread that there is data.
if (dev.inputReportListener != null)
dev.inputReportListener.onInputReport(new InputReportEvent(dev, report_id, dev.inputData, length));
logger.finest("here4.1: report: " + length + ", " + Thread.currentThread());
logger.finest("here4.3: report: " + length + ", " + Thread.currentThread());
}

/** purejavahidapi way */
Expand Down Expand Up @@ -378,7 +379,7 @@ IOHIDDevice getIOHIDDeviceRef(String path) {
@Override
public MacosHidDevice open(HidDevice.Info info) throws IOException {
logger.finer("here00.0: path: " + info.path);
Pointer/* io_registry_entry_t */ entry;
Pointer/* io_registry_entry_t */ entry = null;
MacosHidDevice device = new MacosHidDevice(device_open_options);
device.deviceInfo = info;
try {
Expand Down Expand Up @@ -418,18 +419,18 @@ public MacosHidDevice open(HidDevice.Info info) throws IOException {
// Create the Run Loop Mode for this device.
// printing the reference seems to work.
String str = String.format("HIDAPI_%x", Pointer.nativeValue(device.deviceHandle.device));
logger.finest("here00.2: str: " + str);
device.runLoopMode = CFLib.INSTANCE.CFStringCreateWithCString(null, str.getBytes(StandardCharsets.US_ASCII), CFLib.kCFStringEncodingASCII);
logger.finer("here00.2: str: " + str + ", " + device.runLoopMode.getString());

// Attach the device to a Run Loop
UserObjectContext.ByReference object_context = UserObjectContext.createContext(device);
if (device.maxInputReportLength > 0) {
IOKitLib.INSTANCE.IOHIDDeviceRegisterInputReportCallback(
device.deviceHandle.device, device.inputReportBuffer, CFIndex.of(device.maxInputReportLength),
this::onReportCallback, object_context);
MacosHidDeviceManager::onReportCallback, object_context);
logger.fine("here00.3: start report");
}
IOKitLib.INSTANCE.IOHIDDeviceRegisterRemovalCallback(device.deviceHandle.device, this::onDeviceRemovalCallback, object_context);
IOKitLib.INSTANCE.IOHIDDeviceRegisterRemovalCallback(device.deviceHandle.device, MacosHidDeviceManager::onDeviceRemovalCallback, object_context);

// Start the read thread
device.thread = new Thread(() -> {
Expand All @@ -443,7 +444,7 @@ public MacosHidDevice open(HidDevice.Info info) throws IOException {
CFLib.CFRunLoopSourceContext.ByReference ctx = new CFLib.CFRunLoopSourceContext.ByReference();
ctx.version = CFIndex.of(0);
ctx.info = object_context.getPointer();
ctx.perform = this::onSignalCallback;
ctx.perform = MacosHidDeviceManager::onSignalCallback;
device.source = CFLib.INSTANCE.CFRunLoopSourceCreate(CFAllocator.kCFAllocatorDefault, CFIndex.of(0) /* order */, ctx);
CFLib.INSTANCE.CFRunLoopAddSource(CFLib.INSTANCE.CFRunLoopGetCurrent(), device.source, device.runLoopMode);

Expand All @@ -460,7 +461,7 @@ public MacosHidDevice open(HidDevice.Info info) throws IOException {
int code;
logger.finer("here50.2: dev.shutdownThread: " + !device.shutdownThread + ", !dev.disconnected: " + !device.disconnected);
while (!device.shutdownThread && !device.disconnected) {
code = CFLib.INSTANCE.CFRunLoopRunInMode(device.runLoopMode, 1000 /* sec */, false);
code = CFLib.INSTANCE.CFRunLoopRunInMode(device.runLoopMode, 1/* sec */, false);
// Return if the device has been disconnected
if (code == CFLib.kCFRunLoopRunFinished || code == CFLib.kCFRunLoopRunStopped) {
device.disconnected = true;
Expand All @@ -482,17 +483,13 @@ public MacosHidDevice open(HidDevice.Info info) throws IOException {
// Wait here until hid_close() is called and makes it past
// the call to CFRunLoopWakeUp(). This thread still needs to
// be valid when that function is called on the other thread.
if (!device.disconnected) {
logger.fine("here50.5: notify shutdownBarrier -1");
device.shutdownBarrier.waitAndSync();
device.shutdownBarrier.waitAndSync();
}
logger.fine("here50.6: thread done");
}, str);
device.thread.start();
//new Thread(() -> {
// while (!device.disconnected) {
// /*if (!device.thread.isAlive())*/ logger.info(device.thread + ": is alive?: " + device.thread.isAlive() + ", " + device.thread.getStackTrace()[1]);
// try { Thread.sleep(500); } catch (InterruptedException ignore) {}
// }
//}).start();

// Wait here for the read thread to be initialized.
device.barrier.waitAndSync();
Expand All @@ -503,16 +500,15 @@ public MacosHidDevice open(HidDevice.Info info) throws IOException {
devices.add(device);
logger.fine("here00.4: devices: +: " + device + " / " + devices.size() + ", " + str);
return device;
// } catch (IOException e) {
//logger.log(Level.SEVERE, e.toString(), e);
// if (device.deviceHandle != null)
// CFLib.INSTANCE.CFRelease(device.deviceHandle.device);
//
// if (entry != null)
// IOKitLib.INSTANCE.IOObjectRelease(entry);
//
// throw e;
} finally {
} catch (IOException e) {
logger.log(Level.SEVERE, e.toString(), e);
if (device.deviceHandle != null)
CFLib.INSTANCE.CFRelease(device.deviceHandle.device);

if (entry != null && entry != MACH_PORT_NULL)
IOKitLib.INSTANCE.IOObjectRelease(entry);

throw e;
}
}
}

0 comments on commit 3aa8a93

Please sign in to comment.