geforkt von Mirrors/Velocity
Improve native initialization logic, again
Dieser Commit ist enthalten in:
Ursprung
e75ec71b32
Commit
fc48db62b5
@ -16,13 +16,14 @@ public class NativeCodeLoader<T> implements Supplier<T> {
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
if (selected == null) {
|
||||
selected = tryLoad();
|
||||
}
|
||||
return selected.object;
|
||||
return tryLoad().object;
|
||||
}
|
||||
|
||||
private Variant<T> tryLoad() {
|
||||
if (selected != null) {
|
||||
return selected;
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
if (selected != null) {
|
||||
return selected;
|
||||
@ -41,18 +42,15 @@ public class NativeCodeLoader<T> implements Supplier<T> {
|
||||
}
|
||||
|
||||
public String getLoadedVariant() {
|
||||
if (selected == null) {
|
||||
selected = tryLoad();
|
||||
}
|
||||
return selected.name;
|
||||
return tryLoad().name;
|
||||
}
|
||||
|
||||
static class Variant<T> {
|
||||
private boolean available;
|
||||
private volatile boolean available;
|
||||
private final Runnable setup;
|
||||
private final String name;
|
||||
private final T object;
|
||||
private boolean hasBeenSetup = false;
|
||||
private volatile boolean hasBeenSetup = false;
|
||||
|
||||
Variant(BooleanSupplier available, Runnable setup, String name, T object) {
|
||||
this.available = available.getAsBoolean();
|
||||
@ -61,29 +59,36 @@ public class NativeCodeLoader<T> implements Supplier<T> {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
if (available && !hasBeenSetup) {
|
||||
public T get() {
|
||||
if (!available) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Make sure setup happens only once
|
||||
if (!hasBeenSetup) {
|
||||
synchronized (this) {
|
||||
// We change availability if need be below, may as well check it again here for sanity.
|
||||
if (!available) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Okay, now try the setup if we haven't done so yet.
|
||||
if (!hasBeenSetup) {
|
||||
try {
|
||||
setup.run();
|
||||
hasBeenSetup = true;
|
||||
return object;
|
||||
} catch (Exception e) {
|
||||
available = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public T get() {
|
||||
if (!hasBeenSetup) {
|
||||
setup();
|
||||
}
|
||||
|
||||
if (available) {
|
||||
return object;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
static final BooleanSupplier MACOS = () -> System.getProperty("os.name").equalsIgnoreCase("Mac OS X") &&
|
||||
System.getProperty("os.arch").equals("x86_64");
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren