Native: fix deadlock in kotlinx.cinterop.typeOf impl for JVM

Don't use ConcurrentHashMap.computeIfAbsent for typeOf cache,
because the computation may call typeOf recursively for different type
(e.g. C enum var type computation calls typeOf for enum base integer type),
which might cause a deadlock in computeIfAbsent.
This commit is contained in:
Svyatoslav Scherbina
2021-09-20 19:32:17 +03:00
committed by Space
parent a279f682bb
commit fb81ae0cd1
@@ -35,7 +35,12 @@ private val typeOfCache = ConcurrentHashMap<Class<*>, CVariable.Type>()
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
inline fun <reified T : CVariable> typeOf() =
@Suppress("DEPRECATION")
typeOfCache.computeIfAbsent(T::class.java) { T::class.companionObjectInstance as CVariable.Type }
typeOfCache.getOrPut(T::class.java) { T::class.companionObjectInstance as CVariable.Type }
// Note: not using ^ `computeIfAbsent` because it can cause a deadlock:
// companion object initializer can indirectly use `typeOf` (as it happens for enum "vars"),
// so `computeIfAbsent` would be called recursively for different keys in the case.
// See also the documentation for [ConcurrentHashMap.computeIfAbsent], which
// specifically mentions this problem.
/**
* Returns interpretation of entity with given pointer, or `null` if it is null.