Skip to content

Commit c2e45bf

Browse files
authored
Add double null check pattern when initializing cache values
Fix thread-safety issue with initialization of class cache.
1 parent 6474e6c commit c2e45bf

1 file changed

Lines changed: 18 additions & 8 deletions

File tree

rhino/src/main/java/org/mozilla/javascript/ClassCache.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ public class ClassCache implements Serializable {
2222
private static final long serialVersionUID = -8866246036237312215L;
2323
private static final Object AKEY = "ClassCache";
2424
private volatile boolean cachingIsEnabled = true;
25-
private transient Map<CacheKey, JavaMembers> classTable;
26-
private transient Map<JavaAdapter.JavaAdapterSignature, Class<?>> classAdapterCache;
27-
private transient Map<Class<?>, Object> interfaceAdapterCache;
25+
private transient volatile Map<CacheKey, JavaMembers> classTable;
26+
private transient volatile Map<JavaAdapter.JavaAdapterSignature, Class<?>> classAdapterCache;
27+
private transient volatile Map<Class<?>, Object> interfaceAdapterCache;
2828
private int generatedClassSerial;
2929
private Scriptable associatedScope;
3030

@@ -137,16 +137,22 @@ public synchronized void setCachingEnabled(boolean enabled) {
137137
*/
138138
Map<CacheKey, JavaMembers> getClassCacheMap() {
139139
if (classTable == null) {
140-
// Use 1 as concurrency level here and for other concurrent hash maps
141-
// as we don't expect high levels of sustained concurrent writes.
142-
classTable = new ConcurrentHashMap<>(16, 0.75f, 1);
140+
synchronized (this) {
141+
if (classTable == null) {
142+
classTable = new ConcurrentHashMap<>();
143+
}
144+
}
143145
}
144146
return classTable;
145147
}
146148

147149
Map<JavaAdapter.JavaAdapterSignature, Class<?>> getInterfaceAdapterCacheMap() {
148150
if (classAdapterCache == null) {
149-
classAdapterCache = new ConcurrentHashMap<>(16, 0.75f, 1);
151+
synchronized (this) {
152+
if (classAdapterCache == null) {
153+
classAdapterCache = new ConcurrentHashMap<>();
154+
}
155+
}
150156
}
151157
return classAdapterCache;
152158
}
@@ -184,7 +190,11 @@ Object getInterfaceAdapter(Class<?> cl) {
184190
synchronized void cacheInterfaceAdapter(Class<?> cl, Object iadapter) {
185191
if (cachingIsEnabled) {
186192
if (interfaceAdapterCache == null) {
187-
interfaceAdapterCache = new ConcurrentHashMap<>(16, 0.75f, 1);
193+
synchronized (this) {
194+
if (interfaceAdapterCache == null) {
195+
interfaceAdapterCache = new ConcurrentHashMap<>();
196+
}
197+
}
188198
}
189199
interfaceAdapterCache.put(cl, iadapter);
190200
}

0 commit comments

Comments
 (0)