13
0
geforkt von Mirrors/Velocity

Improve native initialization logic, again

Dieser Commit ist enthalten in:
Andrew Steinborn 2018-09-17 15:02:49 -04:00
Ursprung e75ec71b32
Commit fc48db62b5

Datei anzeigen

@ -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,27 +59,34 @@ public class NativeCodeLoader<T> implements Supplier<T> {
this.object = object;
}
private void setup() {
if (available && !hasBeenSetup) {
try {
setup.run();
hasBeenSetup = true;
} catch (Exception e) {
available = false;
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;
return null;
}
}
}
}
}
public T get() {
if (!hasBeenSetup) {
setup();
}
if (available) {
return object;
}
return null;
return object;
}
}