Skip to content

Commit e9b82ce

Browse files
committed
* Move native Loader methods to Helper class to avoid deadlocks (issue #737)
1 parent 26eb486 commit e9b82ce

File tree

3 files changed

+65
-35
lines changed

3 files changed

+65
-35
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

2+
* Move native `Loader` methods to `Helper` class to avoid deadlocks ([issue #737](https://github.com/bytedeco/javacpp/issues/737))
23
* Fix `Parser` failing to pick up `Info` for constructors with template arguments ([pull #739](https://github.com/bytedeco/javacpp/pull/739))
34
* Fix `MoveAdapter` and `UniquePtrAdapter` causing double free on function calls ([pull #738](https://github.com/bytedeco/javacpp/pull/738))
45
* Fix `Parser` handling of `template` specialization and their `friend` declarations ([pull #733](https://github.com/bytedeco/javacpp/pull/733))

src/main/java/org/bytedeco/javacpp/Loader.java

Lines changed: 62 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1968,16 +1968,6 @@ public static String createLibraryLink(String filename, ClassProperties properti
19681968
static WeakHashMap<Class<? extends Pointer>,HashMap<String,Integer>> memberOffsets =
19691969
new WeakHashMap<Class<? extends Pointer>,HashMap<String,Integer>>();
19701970

1971-
static {
1972-
try {
1973-
Loader.load();
1974-
} catch (Throwable t) {
1975-
if (logger.isDebugEnabled()) {
1976-
logger.debug("Could not load Loader: " + t);
1977-
}
1978-
}
1979-
}
1980-
19811971
/**
19821972
* Called by native libraries to put {@code offsetof()} and {@code sizeof()} values in {@link #memberOffsets}.
19831973
* Tries to load the Class object for typeName using the {@link ClassLoader} of the Loader.
@@ -2044,37 +2034,75 @@ public static int sizeof(Class<? extends Pointer> type) {
20442034
return offsetof(type, "sizeof");
20452035
}
20462036

2037+
public static class Helper {
2038+
static {
2039+
try {
2040+
Loader.load();
2041+
} catch (Throwable t) {
2042+
if (logger.isDebugEnabled()) {
2043+
logger.debug("Could not load Loader.Helper: " + t);
2044+
}
2045+
}
2046+
}
2047+
2048+
/** Returns the number of processors configured according to the operating system, or 0 if unknown.
2049+
* This value can be greater than {@link Runtime#availableProcessors()} and {@link #totalCores()}. */
2050+
@Name("JavaCPP_totalProcessors") public static native int totalProcessors();
2051+
2052+
/** Returns the number of CPU cores usable according to the operating system, or 0 if unknown.
2053+
* For SMT-capable systems, this value may be less than {@link #totalProcessors()}. */
2054+
@Name("JavaCPP_totalCores") public static native int totalCores();
2055+
2056+
/** Returns the number of CPU chips installed according to the operating system, or 0 if unknown.
2057+
* For multi-core processors, this value may be less than {@link #totalCores()}. */
2058+
@Name("JavaCPP_totalChips") public static native int totalChips();
2059+
2060+
/** Returns the address found under the given name in the "dynamic symbol tables" (Linux, Mac OS X, etc)
2061+
* or the "export tables" (Windows) of all libraries loaded, or null if not found. */
2062+
@Name("JavaCPP_addressof") public static native Pointer addressof(String symbol);
2063+
2064+
/** Loads all symbols from a library globally, that is {@code dlopen(filename, RTLD_LAZY | RTLD_GLOBAL)},
2065+
* or simply by default with {@code LoadLibrary(filename)} on Windows. If the library name passed to
2066+
* one of the other load functions in this class ends with "!", this function will get called on them. */
2067+
@Name("JavaCPP_loadGlobal") @Raw(withEnv = true) public static native void loadGlobal(String filename);
2068+
2069+
/** Returns the JavaVM JNI object, as required by some APIs for initialization. */
2070+
@Name("JavaCPP_getJavaVM") public static native @Cast("JavaVM*") Pointer getJavaVM();
2071+
2072+
/** Returns a JNI global reference stored in a Pointer for the given Object. */
2073+
@Name("JavaCPP_newGlobalRef") public static native @Cast("jobject") Pointer newGlobalRef(@Raw(withEnv = true) Object object);
2074+
2075+
/** Returns an Object from the JNI global reference stored in the Pointer. */
2076+
@Name("JavaCPP_accessGlobalRef") @Raw(withEnv = true) public static native Object accessGlobalRef(@Cast("jobject") Pointer globalRef);
2077+
2078+
/** Deletes the JNI global reference stored in the Pointer. */
2079+
@Name("JavaCPP_deleteGlobalRef") @Raw(withEnv = true) public static native void deleteGlobalRef(@Cast("jobject") Pointer globalRef);
2080+
}
20472081

2048-
/** Returns the number of processors configured according to the operating system, or 0 if unknown.
2049-
* This value can be greater than {@link Runtime#availableProcessors()} and {@link #totalCores()}. */
2050-
@Name("JavaCPP_totalProcessors") public static native int totalProcessors();
2082+
/** Returns {@link Helper#totalProcessors()}. */
2083+
public static int totalProcessors() { return Helper.totalProcessors(); }
20512084

2052-
/** Returns the number of CPU cores usable according to the operating system, or 0 if unknown.
2053-
* For SMT-capable systems, this value may be less than {@link #totalProcessors()}. */
2054-
@Name("JavaCPP_totalCores") public static native int totalCores();
2085+
/** Returns {@link Helper#totalCores()}. */
2086+
public static int totalCores() { return Helper.totalCores(); }
20552087

2056-
/** Returns the number of CPU chips installed according to the operating system, or 0 if unknown.
2057-
* For multi-core processors, this value may be less than {@link #totalCores()}. */
2058-
@Name("JavaCPP_totalChips") public static native int totalChips();
2088+
/** Returns {@link Helper#totalChips()}. */
2089+
public static int totalChips() { return Helper.totalChips(); }
20592090

2060-
/** Returns the address found under the given name in the "dynamic symbol tables" (Linux, Mac OS X, etc)
2061-
* or the "export tables" (Windows) of all libraries loaded, or null if not found. */
2062-
@Name("JavaCPP_addressof") public static native Pointer addressof(String symbol);
2091+
/** Returns {@link Helper#addressof(String)}. */
2092+
public static Pointer addressof(String symbol) { return Helper.addressof(symbol); }
20632093

2064-
/** Loads all symbols from a library globally, that is {@code dlopen(filename, RTLD_LAZY | RTLD_GLOBAL)},
2065-
* or simply by default with {@code LoadLibrary(filename)} on Windows. If the library name passed to
2066-
* one of the other load functions in this class ends with "!", this function will get called on them. */
2067-
@Name("JavaCPP_loadGlobal") @Raw(withEnv = true) public static native void loadGlobal(String filename);
2094+
/** Calls {@link Helper#loadGlobal(String)}. */
2095+
public static void loadGlobal(String filename) { Helper.loadGlobal(filename); }
20682096

2069-
/** Returns the JavaVM JNI object, as required by some APIs for initialization. */
2070-
@Name("JavaCPP_getJavaVM") public static native @Cast("JavaVM*") Pointer getJavaVM();
2097+
/** Returns {@link Helper#getJavaVM()}. */
2098+
public static Pointer getJavaVM() { return Helper.getJavaVM(); }
20712099

2072-
/** Returns a JNI global reference stored in a Pointer for the given Object. */
2073-
@Name("JavaCPP_newGlobalRef") public static native @Cast("jobject") Pointer newGlobalRef(@Raw(withEnv = true) Object object);
2100+
/** Returns {@link Helper#newGlobalRef(Object)}. */
2101+
public static Pointer newGlobalRef(Object object) { return Helper.newGlobalRef(object); }
20742102

2075-
/** Returns an Object from the JNI global reference stored in the Pointer. */
2076-
@Name("JavaCPP_accessGlobalRef") @Raw(withEnv = true) public static native Object accessGlobalRef(@Cast("jobject") Pointer globalRef);
2103+
/** Returns {@link Helper#accessGlobalRef(Pointer)}. */
2104+
public static Object accessGlobalRef(Pointer globalRef) { return Helper.accessGlobalRef(globalRef); }
20772105

2078-
/** Deletes the JNI global reference stored in the Pointer. */
2079-
@Name("JavaCPP_deleteGlobalRef") @Raw(withEnv = true) public static native void deleteGlobalRef(@Cast("jobject") Pointer globalRef);
2106+
/** Calls {@link Helper#deleteGlobalRef(Pointer)}. */
2107+
public static void deleteGlobalRef(Pointer globalRef) { Helper.deleteGlobalRef(globalRef); }
20802108
}

src/main/java/org/bytedeco/javacpp/tools/Generator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ static enum IntEnum { INT; int value; }
154154
static enum LongEnum { LONG; long value; }
155155
static final String JNI_VERSION = "JNI_VERSION_1_6";
156156
static final List<Class> baseClasses = Arrays.asList(new Class[] {
157-
Loader.class,
157+
Loader.Helper.class,
158158
Pointer.class,
159159
//FunctionPointer.class,
160160
BytePointer.class,
@@ -2065,6 +2065,7 @@ boolean methods(Class<?> cls) {
20652065
Set<String> memberList = members.get(cls);
20662066
if (!cls.isAnnotationPresent(Opaque.class) && cls != Loader.class
20672067
&& !FunctionPointer.class.isAssignableFrom(cls)
2068+
&& cls.getEnclosingClass() != Loader.class
20682069
&& cls.getEnclosingClass() != Pointer.class) {
20692070
if (memberList == null) {
20702071
members.put(cls, memberList = new LinkedHashSet<String>());

0 commit comments

Comments
 (0)