Skip to content

Commit 196c7fb

Browse files
committed
Fix global map not being accessed via locks
Signed-off-by: TheSilkMiner <thesilkminer@outlook.com>
1 parent 2dc2e2d commit 196c7fb

File tree

1 file changed

+16
-18
lines changed

1 file changed

+16
-18
lines changed

JavaRuntime/src/main/java/org/openzen/zenscript/javart/factory/LambdaFactory.java

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
public final class LambdaFactory {
2525
private static final class LambdaClassLoader extends ClassLoader {
26+
private static final Lock GLOBAL_LOCK = new ReentrantLock();
2627
private static final Map<ClassLoader, WeakReference<LambdaClassLoader>> KNOWN_LOADERS = new WeakHashMap<>();
2728

2829
static {
@@ -39,15 +40,21 @@ private LambdaClassLoader(final ClassLoader parent) {
3940
}
4041

4142
private static LambdaClassLoader findLoader(final MethodHandles.Lookup lookup) {
42-
final ClassLoader lookupClassLoader = lookup.lookupClass().getClassLoader();
43-
final WeakReference<LambdaClassLoader> loaderRef = KNOWN_LOADERS.get(lookupClassLoader);
44-
if (loaderRef == null || loaderRef.get() == null) {
45-
// LambdaClassLoader reference was lost (or it never existed), so recreate
46-
final LambdaClassLoader loader = new LambdaClassLoader(lookupClassLoader);
47-
KNOWN_LOADERS.put(loader, new WeakReference<>(loader));
48-
return loader;
43+
GLOBAL_LOCK.lock();
44+
try {
45+
final ClassLoader lookupClassLoader = lookup.lookupClass().getClassLoader();
46+
final WeakReference<LambdaClassLoader> loaderRef = KNOWN_LOADERS.get(lookupClassLoader);
47+
final LambdaClassLoader alreadyPresentLoader = loaderRef == null? null : loaderRef.get();
48+
if (alreadyPresentLoader == null) {
49+
// LambdaClassLoader reference was lost (or it never existed), so recreate
50+
final LambdaClassLoader loader = new LambdaClassLoader(lookupClassLoader);
51+
KNOWN_LOADERS.put(loader, new WeakReference<>(loader));
52+
return loader;
53+
}
54+
return alreadyPresentLoader;
55+
} finally {
56+
GLOBAL_LOCK.unlock();
4957
}
50-
return loaderRef.get();
5158
}
5259

5360
LambdaClassLoader registerLambda(final String name, final byte[] data) {
@@ -65,25 +72,16 @@ LambdaClassLoader registerLambda(final String name, final byte[] data) {
6572

6673
@Override
6774
protected Class<?> findClass(final String name) throws ClassNotFoundException {
68-
// Step 1: try loading the class directly without locking; there should never be an instance where a thread
69-
// is trying to load a class that is being registered on another thread
70-
Class<?> lambdaClass = this.tryLoadLambdaClass(name);
71-
if (lambdaClass != null) {
72-
return lambdaClass;
73-
}
74-
75-
// Step 2: if the previous step failed, let's retry with locking just in case the above situation happened
7675
this.lock.lock();
7776
try {
78-
lambdaClass = this.tryLoadLambdaClass(name);
77+
final Class<?> lambdaClass = this.tryLoadLambdaClass(name);
7978
if (lambdaClass != null) {
8079
return lambdaClass;
8180
}
8281
} finally {
8382
this.lock.unlock();
8483
}
8584

86-
// Step 3: Defer to default behavior
8785
return super.findClass(name);
8886
}
8987

0 commit comments

Comments
 (0)