mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8282515: More clean up on NativeLibraries just for JNI library use
Reviewed-by: mcimadamore
This commit is contained in:
parent
1485883c9e
commit
02aa7cef0a
6 changed files with 250 additions and 102 deletions
|
@ -190,7 +190,7 @@ public final class NativeLibraries {
|
|||
}
|
||||
}
|
||||
|
||||
NativeLibraryImpl lib = new NativeLibraryImpl(fromClass, name, isBuiltin, true);
|
||||
NativeLibraryImpl lib = new NativeLibraryImpl(fromClass, name, isBuiltin);
|
||||
// load the native library
|
||||
NativeLibraryContext.push(lib);
|
||||
try {
|
||||
|
@ -290,21 +290,16 @@ public final class NativeLibraries {
|
|||
final String name;
|
||||
// Indicates if the native library is linked into the VM
|
||||
final boolean isBuiltin;
|
||||
// Indicate if this is JNI native library
|
||||
final boolean isJNI;
|
||||
|
||||
// opaque handle to native library, used in native code.
|
||||
long handle;
|
||||
// the version of JNI environment the native library requires.
|
||||
int jniVersion;
|
||||
|
||||
NativeLibraryImpl(Class<?> fromClass, String name, boolean isBuiltin, boolean isJNI) {
|
||||
assert !isBuiltin || isJNI : "a builtin native library must be JNI library";
|
||||
|
||||
NativeLibraryImpl(Class<?> fromClass, String name, boolean isBuiltin) {
|
||||
this.fromClass = fromClass;
|
||||
this.name = name;
|
||||
this.isBuiltin = isBuiltin;
|
||||
this.isJNI = isJNI;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -322,7 +317,7 @@ public final class NativeLibraries {
|
|||
* when this class loader becomes phantom reachable.
|
||||
*/
|
||||
private Runnable unloader() {
|
||||
return new Unloader(name, handle, isBuiltin, isJNI);
|
||||
return new Unloader(name, handle, isBuiltin);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -333,14 +328,14 @@ public final class NativeLibraries {
|
|||
throw new InternalError("Native library " + name + " has been loaded");
|
||||
}
|
||||
|
||||
return load(this, name, isBuiltin, isJNI, loadLibraryOnlyIfPresent);
|
||||
return load(this, name, isBuiltin, loadLibraryOnlyIfPresent);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close this native library.
|
||||
*/
|
||||
void close() {
|
||||
unload(name, isBuiltin, isJNI, handle);
|
||||
unload(name, isBuiltin, handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,15 +347,13 @@ public final class NativeLibraries {
|
|||
// This represents the context when a native library is unloaded
|
||||
// and getFromClass() will return null,
|
||||
static final NativeLibraryImpl UNLOADER =
|
||||
new NativeLibraryImpl(null, "dummy", false, false);
|
||||
new NativeLibraryImpl(null, "dummy", false);
|
||||
|
||||
final String name;
|
||||
final long handle;
|
||||
final boolean isBuiltin;
|
||||
final boolean isJNI;
|
||||
|
||||
Unloader(String name, long handle, boolean isBuiltin, boolean isJNI) {
|
||||
assert !isBuiltin || isJNI : "a builtin native library must be JNI library";
|
||||
Unloader(String name, long handle, boolean isBuiltin) {
|
||||
if (handle == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid handle for native library " + name);
|
||||
|
@ -369,7 +362,6 @@ public final class NativeLibraries {
|
|||
this.name = name;
|
||||
this.handle = handle;
|
||||
this.isBuiltin = isBuiltin;
|
||||
this.isJNI = isJNI;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -377,12 +369,12 @@ public final class NativeLibraries {
|
|||
acquireNativeLibraryLock(name);
|
||||
try {
|
||||
/* remove the native library name */
|
||||
if (isJNI && !loadedLibraryNames.remove(name)) {
|
||||
if (!loadedLibraryNames.remove(name)) {
|
||||
throw new IllegalStateException(name + " has already been unloaded");
|
||||
}
|
||||
NativeLibraryContext.push(UNLOADER);
|
||||
try {
|
||||
unload(name, isBuiltin, isJNI, handle);
|
||||
unload(name, isBuiltin, handle);
|
||||
} finally {
|
||||
NativeLibraryContext.pop();
|
||||
}
|
||||
|
@ -524,12 +516,28 @@ public final class NativeLibraries {
|
|||
return NativeLibraryContext.peek().fromClass;
|
||||
}
|
||||
|
||||
// JNI FindClass expects the caller class if invoked from JNI_OnLoad
|
||||
// and JNI_OnUnload is NativeLibrary class
|
||||
/*
|
||||
* Return true if the given library is successfully loaded.
|
||||
* If the given library cannot be loaded for any reason,
|
||||
* if throwExceptionIfFail is false, then this method returns false;
|
||||
* otherwise, UnsatisfiedLinkError will be thrown.
|
||||
*
|
||||
* JNI FindClass expects the caller class if invoked from JNI_OnLoad
|
||||
* and JNI_OnUnload is NativeLibrary class.
|
||||
*/
|
||||
private static native boolean load(NativeLibraryImpl impl, String name,
|
||||
boolean isBuiltin, boolean isJNI,
|
||||
boolean isBuiltin,
|
||||
boolean throwExceptionIfFail);
|
||||
private static native void unload(String name, boolean isBuiltin, boolean isJNI, long handle);
|
||||
/*
|
||||
* Unload the named library. JNI_OnUnload, if present, will be invoked
|
||||
* before the native library is unloaded.
|
||||
*/
|
||||
private static native void unload(String name, boolean isBuiltin, long handle);
|
||||
private static native String findBuiltinLib(String name);
|
||||
private static native long findEntry0(NativeLibraryImpl lib, String name);
|
||||
|
||||
/*
|
||||
* Returns the address of the named symbol defined in the given library.
|
||||
* Returns 0 if not found.
|
||||
*/
|
||||
static native long findEntry0(NativeLibrary lib, String name);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ import static jdk.internal.loader.NativeLibraries.*;
|
|||
* 3. No relationship with class loaders.
|
||||
*/
|
||||
public final class RawNativeLibraries {
|
||||
final Map<String, NativeLibraryImpl> libraries = new ConcurrentHashMap<>();
|
||||
final Map<String, RawNativeLibraryImpl> libraries = new ConcurrentHashMap<>();
|
||||
final Class<?> caller;
|
||||
|
||||
private RawNativeLibraries(MethodHandles.Lookup trustedCaller) {
|
||||
|
@ -116,10 +116,10 @@ public final class RawNativeLibraries {
|
|||
return libraries.computeIfAbsent(pathname, this::get);
|
||||
}
|
||||
|
||||
private NativeLibraryImpl get(String pathname) {
|
||||
NativeLibraryImpl lib = new NativeLibraryImpl(caller, pathname, false, false);
|
||||
private RawNativeLibraryImpl get(String pathname) {
|
||||
RawNativeLibraryImpl lib = new RawNativeLibraryImpl(caller, pathname);
|
||||
if (!lib.open()) {
|
||||
return null; // fail to open the native library
|
||||
return null;
|
||||
}
|
||||
return lib;
|
||||
}
|
||||
|
@ -132,8 +132,49 @@ public final class RawNativeLibraries {
|
|||
if (!libraries.remove(lib.name(), lib)) {
|
||||
throw new IllegalArgumentException(lib.name() + " not loaded by this RawNativeLibraries instance");
|
||||
}
|
||||
NativeLibraryImpl nl = (NativeLibraryImpl)lib;
|
||||
RawNativeLibraryImpl nl = (RawNativeLibraryImpl)lib;
|
||||
nl.close();
|
||||
}
|
||||
|
||||
static class RawNativeLibraryImpl implements NativeLibrary {
|
||||
// the name of the raw native library.
|
||||
final String name;
|
||||
// opaque handle to raw native library, used in native code.
|
||||
long handle;
|
||||
|
||||
RawNativeLibraryImpl(Class<?> fromClass, String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long find(String name) {
|
||||
return findEntry0(this, name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads the named native library.
|
||||
*/
|
||||
boolean open() {
|
||||
if (handle != 0) {
|
||||
throw new InternalError("Native library " + name + " has been loaded");
|
||||
}
|
||||
return load0(this, name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Close this native library.
|
||||
*/
|
||||
void close() {
|
||||
unload0(name, handle);
|
||||
}
|
||||
}
|
||||
|
||||
private static native boolean load0(RawNativeLibraryImpl impl, String name);
|
||||
private static native void unload0(String name, long handle);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue