mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-24 01:31:46 +00:00
Improve JNI loading efficiency (#1224)
A hash is stored for each native library with the name libraryName.hash. If the library is not found on the system search path, it is extracted to a cache directory. Extracted libraries are named with the hash appended, so the library will not be re-extracted if one with the same hash already exists. Hashing without the hash file requires double traversing if the file is not in the cache, but it is still faster than creating a new file in most cases. This won't be needed after opencv is updated to provide a hash as well.
This commit is contained in:
committed by
Peter Johnson
parent
cbb62fb98f
commit
00c2cd7dab
@@ -7,63 +7,28 @@
|
||||
|
||||
package edu.wpi.first.wpilibj.hal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import edu.wpi.first.wpiutil.RuntimeDetector;
|
||||
import edu.wpi.first.wpiutil.RuntimeLoader;
|
||||
|
||||
/**
|
||||
* Base class for all JNI wrappers.
|
||||
*/
|
||||
public class JNIWrapper {
|
||||
static boolean libraryLoaded = false;
|
||||
static File jniLibrary = null;
|
||||
static RuntimeLoader<JNIWrapper> loader = null;
|
||||
|
||||
static {
|
||||
if (!libraryLoaded) {
|
||||
String jniFileName = "wpiHal";
|
||||
try {
|
||||
System.loadLibrary(jniFileName);
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
try {
|
||||
String resname = RuntimeDetector.getLibraryResource(jniFileName);
|
||||
InputStream is = JNIWrapper.class.getResourceAsStream(resname);
|
||||
if (is != null) {
|
||||
// create temporary file
|
||||
if (System.getProperty("os.name").startsWith("Windows")) {
|
||||
jniLibrary = File.createTempFile(jniFileName, ".dll");
|
||||
} else if (System.getProperty("os.name").startsWith("Mac")) {
|
||||
jniLibrary = File.createTempFile(jniFileName, ".dylib");
|
||||
} else {
|
||||
jniLibrary = File.createTempFile(jniFileName, ".so");
|
||||
}
|
||||
// flag for delete on exit
|
||||
jniLibrary.deleteOnExit();
|
||||
OutputStream os = new FileOutputStream(jniLibrary);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int readBytes;
|
||||
try {
|
||||
while ((readBytes = is.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, readBytes);
|
||||
}
|
||||
} finally {
|
||||
os.close();
|
||||
is.close();
|
||||
}
|
||||
System.load(jniLibrary.getAbsolutePath());
|
||||
} else {
|
||||
System.loadLibrary(jniFileName);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
loader = new RuntimeLoader<>("wpiHal", RuntimeLoader.getDefaultExtractionRoot(), JNIWrapper.class);
|
||||
loader.loadLibrary();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
libraryLoaded = true;
|
||||
libraryLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user