From a4d3ab69da28a453d34fff351780ecaf23d02f42 Mon Sep 17 00:00:00 2001 From: Luca Longinotti Date: Wed, 12 Jun 2013 21:39:02 +0200 Subject: [PATCH] Destroying the default context twice, even if it is refcounted, results in a segfault. Fix submitted to libusbx as pull request #116. Also fix this inside the Java wrapper, by adding our own refcount (similar to what was in original usb4java, but allowing multiple calls with the default context), and making the access to said variable thread-safe. Once libusbx fixes this, the above code can be removed. --- src/main/c/src/LibUsb.c | 28 ++++++++++++------- .../java/de/ailis/usb4java/libusb/LibUsb.java | 4 +-- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/main/c/src/LibUsb.c b/src/main/c/src/LibUsb.c index 99e22ef..748cf64 100644 --- a/src/main/c/src/LibUsb.c +++ b/src/main/c/src/LibUsb.c @@ -23,6 +23,8 @@ #include "ConfigDescriptor.h" #include "Transfer.h" +static int defaultContextRefcnt = 0; + /** * Version getVersion() */ @@ -44,7 +46,9 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, init) { if (!context) { - return libusb_init(NULL); + int result = libusb_init(NULL); + if (result == LIBUSB_SUCCESS) defaultContextRefcnt++; + return result; } else { @@ -65,19 +69,23 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, exit) JNIEnv *env, jclass class, jobject context ) { - if (!context) - { - libusb_exit(NULL); - } - else - { - libusb_context *ctx = unwrapContext(env, context); - if (!ctx) return; + if (!context) + { + if (defaultContextRefcnt <= 0) return; + + libusb_exit(NULL); + + defaultContextRefcnt--; + } + else + { + libusb_context *ctx = unwrapContext(env, context); + if (!ctx) return; libusb_exit(ctx); resetContext(env, context); - } + } } /** diff --git a/src/main/java/de/ailis/usb4java/libusb/LibUsb.java b/src/main/java/de/ailis/usb4java/libusb/LibUsb.java index a48f0a3..cceac40 100644 --- a/src/main/java/de/ailis/usb4java/libusb/LibUsb.java +++ b/src/main/java/de/ailis/usb4java/libusb/LibUsb.java @@ -525,7 +525,7 @@ public final class LibUsb * * @see Contexts */ - public static native int init(final Context context); + public static synchronized native int init(final Context context); /** * Deinitialize libusb. @@ -537,7 +537,7 @@ public final class LibUsb * The {@link Context} to deinitialize, or NULL for the default * context. */ - public static native void exit(final Context context); + public static synchronized native void exit(final Context context); /** * Set log message verbosity.