[FIR IDE] Make one global lock for resolve
This commit is contained in:
+6
-20
@@ -7,28 +7,14 @@ package org.jetbrains.kotlin.idea.fir.low.level.api
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE
|
import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
|
||||||
import kotlin.concurrent.withLock
|
|
||||||
|
|
||||||
internal class FirPhaseRunner {
|
internal class FirPhaseRunner {
|
||||||
private val superTypesBodyResolveLock = ReentrantLock()
|
/**
|
||||||
private val statusResolveLock = ReentrantLock()
|
* We temporary disable multi-locks to fix deadlocks problem
|
||||||
private val implicitTypesResolveLock = ReentrantLock()
|
* @see org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.LockProvider
|
||||||
|
*/
|
||||||
inline fun runPhaseWithCustomResolve(phase: FirResolvePhase, crossinline resolve: () -> Unit) = when (phase) {
|
inline fun runPhaseWithCustomResolve(phase: FirResolvePhase, crossinline resolve: () -> Unit) =
|
||||||
FirResolvePhase.SUPER_TYPES -> superTypesBodyResolveLock.withLock {
|
runPhaseWithCustomResolveWithoutLock(resolve)
|
||||||
runPhaseWithCustomResolveWithoutLock(resolve)
|
|
||||||
}
|
|
||||||
FirResolvePhase.STATUS -> statusResolveLock.withLock {
|
|
||||||
runPhaseWithCustomResolveWithoutLock(resolve)
|
|
||||||
}
|
|
||||||
FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE -> implicitTypesResolveLock.withLock {
|
|
||||||
runPhaseWithCustomResolveWithoutLock(resolve)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
runPhaseWithCustomResolveWithoutLock(resolve)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inline fun runPhaseWithCustomResolveWithoutLock(crossinline resolve: () -> Unit) {
|
private inline fun runPhaseWithCustomResolveWithoutLock(crossinline resolve: () -> Unit) {
|
||||||
executeWithoutPCE {
|
executeWithoutPCE {
|
||||||
|
|||||||
+7
-17
@@ -5,36 +5,26 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.fir.low.level.api.file.builder
|
package org.jetbrains.kotlin.idea.fir.low.level.api.file.builder
|
||||||
|
|
||||||
import com.google.common.collect.MapMaker
|
|
||||||
import com.google.common.util.concurrent.CycleDetectingLockFactory
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.PrivateForInline
|
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.PrivateForInline
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.lockWithPCECheck
|
import org.jetbrains.kotlin.idea.fir.low.level.api.util.lockWithPCECheck
|
||||||
import java.util.concurrent.ConcurrentMap
|
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
import kotlin.concurrent.withLock
|
import kotlin.concurrent.withLock
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keyed locks provider.
|
||||||
|
* !!! We temporary remove its correct implementation to fix deadlocks problem. Do not use this until this comment is present
|
||||||
|
*/
|
||||||
internal class LockProvider<KEY> {
|
internal class LockProvider<KEY> {
|
||||||
private val locks: ConcurrentMap<KEY, ReentrantLock> = MapMaker().weakKeys().makeMap()
|
val globalLock = ReentrantLock()
|
||||||
|
|
||||||
@Suppress("UnstableApiUsage")
|
|
||||||
private val lockFactory = CycleDetectingLockFactory.newInstance(CycleDetectingLockFactory.Policies.THROW)
|
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
private inline fun getLockFor(key: KEY) = locks.getOrPut(key) {
|
|
||||||
val file = key as FirFile
|
|
||||||
val name = "${file.packageDirective.packageFqName.asString()}.${file.name}"
|
|
||||||
@Suppress("UnstableApiUsage")
|
|
||||||
lockFactory.newReentrantLock(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
@OptIn(PrivateForInline::class)
|
||||||
inline fun <R> withWriteLock(key: KEY, action: () -> R): R =
|
inline fun <R> withWriteLock(key: KEY, action: () -> R): R =
|
||||||
getLockFor(key).withLock(action)
|
globalLock.withLock(action)
|
||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
@OptIn(PrivateForInline::class)
|
||||||
inline fun <R> withWriteLockPCECheck(key: KEY, lockingIntervalMs: Long, action: () -> R): R =
|
inline fun <R> withWriteLockPCECheck(key: KEY, lockingIntervalMs: Long, action: () -> R): R =
|
||||||
getLockFor(key).lockWithPCECheck(lockingIntervalMs, action)
|
globalLock.lockWithPCECheck(lockingIntervalMs, action) //We temporary disable multi-locks to fix deadlocks problem
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user