Skip to content

Commit 276504f

Browse files
committed
Make fieldAccess and methodAccess thread-safe
1 parent 448c13d commit 276504f

1 file changed

Lines changed: 30 additions & 10 deletions

File tree

foundry-core/src/main/java/org/machinemc/foundry/util/ClassAccess.java

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.util.Arrays;
1414
import java.util.Map;
1515
import java.util.concurrent.ConcurrentHashMap;
16+
import java.util.function.Supplier;
1617

1718
public final class ClassAccess {
1819

@@ -105,38 +106,57 @@ public static <S, T> FieldAccess<S, T> field(Class<S> source, String name) throw
105106
}
106107

107108
private static <S, T> FieldAccess<S, T> fieldAccess(FieldAccessKey<S> key) throws NoSuchFieldException {
108-
FieldAccess<?, ?> fieldAccess = fieldCache.get(key);
109-
if (fieldAccess == null) {
109+
//noinspection unchecked
110+
FieldAccess<S, T> fieldAccess = (FieldAccess<S, T>) fieldCache.get(key);
111+
if (fieldAccess != null)
112+
return fieldAccess;
113+
114+
synchronized (fieldCache) {
115+
//noinspection unchecked
116+
fieldAccess = (FieldAccess<S, T>) fieldCache.get(key);
117+
if (fieldAccess != null)
118+
return fieldAccess;
119+
110120
Class<?> generated = defineHiddenIn(key.source(), generateFieldAccess(key));
111121
try {
112-
fieldAccess = (FieldAccess<?, ?>) generated.getDeclaredConstructor().newInstance();
122+
//noinspection unchecked
123+
fieldAccess = (FieldAccess<S, T>) generated.getDeclaredConstructor().newInstance();
113124
fieldCache.put(key, fieldAccess);
114125
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
115126
throw new RuntimeException(e); // Should not happen
116127
}
117128
}
118-
//noinspection unchecked
119-
return (FieldAccess<S, T>) fieldAccess;
120129

130+
return fieldAccess;
121131
}
122132

123133
public static <S, T> MethodAccess<S, T> method(Class<S> source, String name, Class<?>... parameters) throws NoSuchMethodException {
124134
return methodAccess(new MethodAccessKey<>(source, name, parameters));
125135
}
126136

127137
private static <S, T> MethodAccess<S, T> methodAccess(MethodAccessKey<S> key) throws NoSuchMethodException {
128-
MethodAccess<?, ?> methodAccess = methodCache.get(key);
129-
if (methodAccess == null) {
138+
//noinspection unchecked
139+
MethodAccess<S, T> methodAccess = (MethodAccess<S, T>) methodCache.get(key);
140+
if (methodAccess != null)
141+
return methodAccess;
142+
143+
synchronized (methodCache) {
144+
//noinspection unchecked
145+
methodAccess = (MethodAccess<S, T>) methodCache.get(key);
146+
if (methodAccess != null)
147+
return methodAccess;
148+
130149
Class<?> generated = defineHiddenIn(key.source(), generateMethodAccess(key));
131150
try {
132-
methodAccess = (MethodAccess<?, ?>) generated.getDeclaredConstructor().newInstance();
151+
//noinspection unchecked
152+
methodAccess = (MethodAccess<S, T>) generated.getDeclaredConstructor().newInstance();
133153
methodCache.put(key, methodAccess);
134154
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
135155
throw new RuntimeException(e); // Should not happen
136156
}
137157
}
138-
//noinspection unchecked
139-
return (MethodAccess<S, T>) methodAccess;
158+
159+
return methodAccess;
140160
}
141161

142162
private static Class<?> defineHiddenIn(Class<?> host, byte[] bytes) {

0 commit comments

Comments
 (0)