Try to acquire LC lock with a smaller time window with checkCancels

#KTIJ-28688


Merge-request: KT-MR-14735
Merged-by: Vladimir Dolzhenko <Vladimir.Dolzhenko@jetbrains.com>
This commit is contained in:
Vladimir Dolzhenko
2024-03-04 16:57:32 +00:00
committed by Space Team
parent 82255d5ee8
commit ca88e6e834
@@ -5,12 +5,15 @@
package org.jetbrains.kotlin.asJava.classes package org.jetbrains.kotlin.asJava.classes
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiManager import com.intellij.psi.PsiManager
import com.intellij.psi.impl.PsiCachedValueImpl import com.intellij.psi.impl.PsiCachedValueImpl
import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValueProvider
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.locks.ReentrantLock
import kotlin.time.DurationUnit
import kotlin.time.toDuration
class LightClassesLazyCreator(private val project: Project) : KotlinClassInnerStuffCache.LazyCreator() { class LightClassesLazyCreator(private val project: Project) : KotlinClassInnerStuffCache.LazyCreator() {
override fun <T : Any> get(initializer: () -> T, dependencies: List<Any>) = object : Lazy<T> { override fun <T : Any> get(initializer: () -> T, dependencies: List<Any>) = object : Lazy<T> {
@@ -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 // 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)) { val timeout = 5.toDuration(DurationUnit.SECONDS)
try { val stepTimeout = 500.toDuration(DurationUnit.MILLISECONDS)
initIsRunning.set(true)
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 { try {
computeValue() initIsRunning.set(true)
try {
calculatedValue = computeValue()
} finally {
initIsRunning.set(false)
}
} finally { } finally {
initIsRunning.set(false) lock.unlock()
} }
} finally {
lock.unlock()
} }
} else {
computeValue()
} }
calculatedValue ?: computeValue()
} }
} }