@@ -205,7 +205,7 @@ public final class CApiContext extends CExtContext {
205
205
* in single-context mode). Will be {@code null} in case of multiple contexts.
206
206
*/
207
207
@ CompilationFinal (dimensions = 1 ) private static Object [] nativeSymbolCacheSingleContext ;
208
- private static final AtomicBoolean STATIC_SYMBOL_CACHE_USED = new AtomicBoolean () ;
208
+ private static boolean nativeSymbolCacheSingleContextUsed ;
209
209
210
210
/**
211
211
* A private (i.e. per-context) cache of C API symbols (usually helper functions).
@@ -259,25 +259,28 @@ public CApiContext(PythonContext context, Object llvmLibrary, boolean useNativeB
259
259
* 'CApiContext.nativeSymbolCacheSingleContext != null', the context is safe to use it and
260
260
* just needs to do a null check.
261
261
*/
262
- if (!STATIC_SYMBOL_CACHE_USED .compareAndExchange (false , true ) && context .getLanguage ().isSingleContext ()) {
263
- assert CApiContext .nativeSymbolCacheSingleContext == null ;
262
+ synchronized (CApiContext .class ) {
263
+ if (!CApiContext .nativeSymbolCacheSingleContextUsed && context .getLanguage ().isSingleContext ()) {
264
+ assert CApiContext .nativeSymbolCacheSingleContext == null ;
264
265
265
- // we cannot be in built-time code because this is using pre-initialized contexts
266
- assert !ImageInfo .inImageBuildtimeCode ();
266
+ // we cannot be in built-time code because this is using pre-initialized contexts
267
+ assert !ImageInfo .inImageBuildtimeCode ();
267
268
268
- // this is the first context accessing the static symbol cache
269
- CApiContext .nativeSymbolCacheSingleContext = this .nativeSymbolCache ;
270
- } else if (CApiContext .nativeSymbolCacheSingleContext != null ) {
271
- /*
272
- * In this case, this context instance is at least the second one attempting to use the
273
- * static symbol cache. We now clear the static field to indicate that every context
274
- * instance should use its private cache. If a former context already used the cache and
275
- * there is already compiled code, it is not necessary to invalidate the code because
276
- * the cache is still valid.
277
- */
278
- CApiContext .nativeSymbolCacheSingleContext = null ;
269
+ // this is the first context accessing the static symbol cache
270
+ CApiContext .nativeSymbolCacheSingleContext = this .nativeSymbolCache ;
271
+ CApiContext .nativeSymbolCacheSingleContextUsed = true ;
272
+ } else if (CApiContext .nativeSymbolCacheSingleContext != null ) {
273
+ /*
274
+ * In this case, this context instance is at least the second one attempting to use
275
+ * the static symbol cache. We now clear the static field to indicate that every
276
+ * context instance should use its private cache. If a former context already used
277
+ * the cache and there is already compiled code, it is not necessary to invalidate
278
+ * the code because the cache is still valid.
279
+ */
280
+ CApiContext .nativeSymbolCacheSingleContext = null ;
281
+ }
282
+ assert CApiContext .nativeSymbolCacheSingleContextUsed ;
279
283
}
280
- assert STATIC_SYMBOL_CACHE_USED .get ();
281
284
282
285
// initialize primitive native wrapper cache
283
286
primitiveNativeWrapperCache = new PrimitiveNativeWrapper [262 ];
@@ -820,9 +823,11 @@ public void finalizeCapi() {
820
823
* was the exclusive user of it. We can now reset the state such that other contexts created
821
824
* after this can use it.
822
825
*/
823
- if (CApiContext .nativeSymbolCacheSingleContext != null ) {
824
- CApiContext .nativeSymbolCacheSingleContext = null ;
825
- CApiContext .STATIC_SYMBOL_CACHE_USED .set (false );
826
+ synchronized (CApiContext .class ) {
827
+ if (CApiContext .nativeSymbolCacheSingleContext != null ) {
828
+ CApiContext .nativeSymbolCacheSingleContext = null ;
829
+ CApiContext .nativeSymbolCacheSingleContextUsed = false ;
830
+ }
826
831
}
827
832
}
828
833
0 commit comments