diff --git a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/LightClassesLazyCreator.kt b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/LightClassesLazyCreator.kt index a0eacf74668..84feb417158 100644 --- a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/LightClassesLazyCreator.kt +++ b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/LightClassesLazyCreator.kt @@ -5,12 +5,15 @@ package org.jetbrains.kotlin.asJava.classes +import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.Project import com.intellij.psi.PsiManager import com.intellij.psi.impl.PsiCachedValueImpl import com.intellij.psi.util.CachedValueProvider import java.util.concurrent.TimeUnit import java.util.concurrent.locks.ReentrantLock +import kotlin.time.DurationUnit +import kotlin.time.toDuration class LightClassesLazyCreator(private val project: Project) : KotlinClassInnerStuffCache.LazyCreator() { override fun get(initializer: () -> T, dependencies: List) = object : Lazy { @@ -42,20 +45,30 @@ class LightClassesLazyCreator(private val project: Project) : KotlinClassInnerSt // TODO: NOTE: acquire lock for a several seconds to avoid dead-lock via resolve is a WORKAROUND - if (!initIsRunning.get() && lock.tryLock(5, TimeUnit.SECONDS)) { - try { - initIsRunning.set(true) + val timeout = 5.toDuration(DurationUnit.SECONDS) + val stepTimeout = 500.toDuration(DurationUnit.MILLISECONDS) + + var calculatedValue: T? = null + for (attempt in 0 until (timeout.inWholeMilliseconds / stepTimeout.inWholeMilliseconds)) { + if (calculatedValue != null || initIsRunning.get()) break + + ProgressManager.checkCanceled() + + if (lock.tryLock(stepTimeout.inWholeMilliseconds, TimeUnit.MILLISECONDS)) { try { - computeValue() + initIsRunning.set(true) + try { + calculatedValue = computeValue() + } finally { + initIsRunning.set(false) + } } finally { - initIsRunning.set(false) + lock.unlock() } - } finally { - lock.unlock() } - } else { - computeValue() } + + calculatedValue ?: computeValue() } }