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:
committed by
Space Team
parent
82255d5ee8
commit
ca88e6e834
+22
-9
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user