diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/api/FirModuleResolveState.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/api/FirModuleResolveState.kt index 4850b8649db..1b0f083335a 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/api/FirModuleResolveState.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/api/FirModuleResolveState.kt @@ -20,7 +20,6 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.FirTransformerProvider import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache -import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.withReadLock import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSourcesSession import org.jetbrains.kotlin.idea.fir.low.level.api.util.ktDeclaration import org.jetbrains.kotlin.idea.util.getElementTextInContext diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/FirFileBuilder.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/FirFileBuilder.kt index 718d0ba6a18..a8c1a454db2 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/FirFileBuilder.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/FirFileBuilder.kt @@ -68,10 +68,8 @@ internal class FirFileBuilder( inline fun runCustomResolveUnderLock(firFile: FirFile, cache: ModuleFileCache, resolve: () -> R): R = cache.firFileLockProvider.withWriteLock(firFile) { resolve() } - inline fun runCustomResolveWithPCECheck(firFile: FirFile, cache: ModuleFileCache, resolve: () -> R): R { - val lock = cache.firFileLockProvider.getLockFor(firFile) - return lock.writeLock().lockWithPCECheck(LOCKING_INTERVAL_MS) { resolve() } - } + inline fun runCustomResolveWithPCECheck(firFile: FirFile, cache: ModuleFileCache, resolve: () -> R): R = + cache.firFileLockProvider.withWriteLockPCECheck(firFile, LOCKING_INTERVAL_MS, resolve) fun runResolveWithoutLock( firFile: FirFile, diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/LockProvider.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/LockProvider.kt index fbb6e70f7e3..7011942030e 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/LockProvider.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/LockProvider.kt @@ -6,28 +6,33 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.file.builder import com.google.common.collect.MapMaker +import com.intellij.openapi.diagnostic.logger +import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.idea.fir.low.level.api.util.lockWithPCECheck import java.util.concurrent.ConcurrentMap import java.util.concurrent.locks.ReadWriteLock -import java.util.concurrent.locks.ReentrantLock +import java.util.concurrent.locks.ReentrantReadWriteLock import kotlin.concurrent.withLock -internal class LockProvider(private val createLock: () -> LOCK) { - private val locks: ConcurrentMap = MapMaker().weakKeys().makeMap() - fun getLockFor(key: KEY) = locks.getOrPut(key) { createLock() } -} +internal class LockProvider { + private val locks: ConcurrentMap = MapMaker().weakKeys().makeMap() -internal inline fun LockProvider.withReadLock(key: KEY, action: () -> R): R { - val readLock = getLockFor(key).readLock() - return readLock.withLock { action() } -} + @Suppress("NOTHING_TO_INLINE") + private inline fun getLockFor(key: KEY) = locks.getOrPut(key) { ReentrantReadWriteLock() } -internal inline fun LockProvider.withWriteLock(key: KEY, action: () -> R): R { - val writeLock = getLockFor(key).writeLock() - return writeLock.withLock { action() } -} + inline fun withReadLock(key: KEY, action: () -> R): R { + val readLock = getLockFor(key).readLock() + return readLock.withLock { action() } + } -internal inline fun LockProvider.withLock(key: KEY, action: () -> R): R { - val lock = getLockFor(key) - return lock.withLock { action() } + inline fun withWriteLock(key: KEY, action: () -> R): R { + val writeLock = getLockFor(key).writeLock() + return writeLock.withLock { action() } + } + + inline fun withWriteLockPCECheck(key: KEY, lockingIntervalMs: Long, action: () -> R): R { + val writeLock = getLockFor(key).writeLock() + return writeLock.lockWithPCECheck(lockingIntervalMs, action) + } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/ModuleFileCache.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/ModuleFileCache.kt index 6f7e273f381..47933d45c81 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/ModuleFileCache.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/builder/ModuleFileCache.kt @@ -51,7 +51,7 @@ internal abstract class ModuleFileCache { abstract fun getCachedFirFile(ktFile: KtFile): FirFile? - abstract val firFileLockProvider: LockProvider + abstract val firFileLockProvider: LockProvider inline fun withReadLockOn(declaration: D, action: (D) -> R): R { val file = getContainerFirFile(declaration) @@ -76,5 +76,5 @@ internal class ModuleFileCacheImpl(override val session: FirSession) : ModuleFil return getCachedFirFile(ktFile) } - override val firFileLockProvider: LockProvider = LockProvider { ReentrantReadWriteLock() } + override val firFileLockProvider: LockProvider = LockProvider() } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructure.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructure.kt index cdfbf7313b4..8b8b0382b7b 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructure.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructure.kt @@ -12,8 +12,6 @@ import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.getNonLocalContainingOrThisDeclaration import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache -import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.withReadLock -import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.withWriteLock import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider import org.jetbrains.kotlin.idea.fir.low.level.api.util.findSourceNonLocalFirDeclaration diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/util/utils.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/util/utils.kt index 066e0e23cda..439aef3ff27 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/util/utils.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/util/utils.kt @@ -32,7 +32,7 @@ internal inline fun executeWithoutPCE(crossinline action: () -> T): T return result!! } -internal inline fun Lock.lockWithPCECheck(lockingIntervalMs: Long, action: () -> T): T { +internal inline fun Lock.lockWithPCECheck(lockingIntervalMs: Long, action: () -> T): T { var needToRun = true var result: T? = null while (needToRun) {