mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-347617: let NBRA.inSmartMode, DumbService.{runWhenSmart and smartInvokeLater} wait for the same condition
GitOrigin-RevId: d751da7aba8979fc455937c24079aa1563e45530
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a4eb2dd8ed
commit
2bfa85dc14
+9
-1
@@ -10,7 +10,9 @@ import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.application.constraints.ConstrainedExecution.ContextConstraint
|
||||
import com.intellij.openapi.application.constraints.Expiration
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.DumbServiceImpl
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.impl.PsiDocumentManagerBase
|
||||
@@ -174,7 +176,13 @@ internal class InSmartMode(private val project: Project) : ContextConstraint {
|
||||
}
|
||||
}
|
||||
|
||||
override fun isCorrectContext(): Boolean = !project.isDisposed && !DumbService.isDumb(project)
|
||||
override fun isCorrectContext(): Boolean {
|
||||
val correctContext = !project.isDisposed && DumbServiceImpl.getInstance(project).runWhenSmartCondition.asBoolean
|
||||
if (!correctContext) {
|
||||
thisLogger().debug("InSmartMode dispatched")
|
||||
}
|
||||
return correctContext
|
||||
}
|
||||
|
||||
override fun schedule(runnable: Runnable) {
|
||||
DumbService.getInstance(project).runWhenSmart(runnable)
|
||||
|
||||
@@ -47,6 +47,7 @@ import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import java.util.concurrent.locks.LockSupport
|
||||
import java.util.function.BooleanSupplier
|
||||
import javax.swing.JComponent
|
||||
|
||||
@ApiStatus.Internal
|
||||
@@ -344,6 +345,14 @@ open class DumbServiceImpl @NonInjectable @VisibleForTesting constructor(private
|
||||
myProject.getService(SmartModeScheduler::class.java).runWhenSmart(runnable)
|
||||
}
|
||||
|
||||
internal val runWhenSmartCondition: BooleanSupplier
|
||||
get() = if (useSynchronousTaskQueue) {
|
||||
BooleanSupplier { !isDumb }
|
||||
}
|
||||
else {
|
||||
myProject.getService(SmartModeScheduler::class.java).runWhenSmartCondition
|
||||
}
|
||||
|
||||
override fun unsafeRunWhenSmart(@Async.Schedule runnable: Runnable) {
|
||||
// we probably don't need unsafeRunWhenSmart anymore
|
||||
runWhenSmart(runnable)
|
||||
@@ -563,11 +572,12 @@ open class DumbServiceImpl @NonInjectable @VisibleForTesting constructor(private
|
||||
|
||||
override fun smartInvokeLater(runnable: Runnable, modalityState: ModalityState) {
|
||||
ApplicationManager.getApplication().invokeLater({
|
||||
if (isDumb) {
|
||||
runWhenSmart { smartInvokeLater(runnable, modalityState) }
|
||||
if (runWhenSmartCondition.asBoolean) {
|
||||
runnable.run()
|
||||
}
|
||||
else {
|
||||
runnable.run()
|
||||
LOG.debug("smartInvokeLater dispatched")
|
||||
runWhenSmart { smartInvokeLater(runnable, modalityState) }
|
||||
}
|
||||
}, modalityState, myProject.disposed)
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import org.jetbrains.annotations.Async
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentLinkedDeque
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import java.util.function.BooleanSupplier
|
||||
import java.util.function.Consumer
|
||||
|
||||
/**
|
||||
@@ -53,6 +55,7 @@ class SmartModeScheduler(private val project: Project, sc: CoroutineScope) : Dis
|
||||
private val filesScannerExecutor get() = UnindexedFilesScannerExecutor.getInstance(project)
|
||||
private val projectDumbState: StateFlow<DumbServiceImpl.DumbState> = dumbServiceImpl.dumbStateAsFlow
|
||||
private val projectScanningChanged: Flow<*> = filesScannerExecutor.startedOrStoppedEvent
|
||||
internal val runWhenSmartCondition: BooleanSupplier = BooleanSupplier { getCurrentMode() == 0 }
|
||||
|
||||
init {
|
||||
project.messageBus.simpleConnect().subscribe(DynamicPluginListener.TOPIC, object : DynamicPluginListener {
|
||||
@@ -86,7 +89,7 @@ class SmartModeScheduler(private val project: Project, sc: CoroutineScope) : Dis
|
||||
|
||||
private fun onStateChanged() {
|
||||
LOG.info("State changed. Current mode: ${getCurrentMode()}")
|
||||
if (isSmart()) {
|
||||
if (runWhenSmartCondition.asBoolean) {
|
||||
// Always reschedule execution to avoid unexpected write lock acquired.
|
||||
//
|
||||
// Note2: DumbService tracks modality by itself: exit event occurs in the same modality as the enter event.
|
||||
@@ -96,7 +99,7 @@ class SmartModeScheduler(private val project: Project, sc: CoroutineScope) : Dis
|
||||
}
|
||||
|
||||
fun runWhenSmart(runnable: Runnable) {
|
||||
if (isSmart() && ApplicationManager.getApplication().isDispatchThread) {
|
||||
if (runWhenSmartCondition.asBoolean && ApplicationManager.getApplication().isDispatchThread) {
|
||||
// Execute immediately only because some tests expect this behavior. No production need.
|
||||
runnable.run()
|
||||
}
|
||||
@@ -114,7 +117,7 @@ class SmartModeScheduler(private val project: Project, sc: CoroutineScope) : Dis
|
||||
|
||||
// It may happen that one of the pending runWhenSmart actions triggers new dumb mode;
|
||||
// in this case we should quit processing pending actions and postpone them until the newly started dumb mode finishes.
|
||||
while (isSmart()) {
|
||||
while (runWhenSmartCondition.asBoolean) {
|
||||
val runnable = myRunWhenSmartQueue.pollFirst() ?: break
|
||||
resetThreadContext().use {
|
||||
doRun(runnable)
|
||||
@@ -135,7 +138,6 @@ class SmartModeScheduler(private val project: Project, sc: CoroutineScope) : Dis
|
||||
}
|
||||
}
|
||||
|
||||
private fun isSmart() = (getCurrentMode() == 0)
|
||||
fun getCurrentMode(): Int =
|
||||
(if (filesScannerExecutor.isRunning.value) SCANNING else 0) +
|
||||
(if (projectDumbState.value.isDumb) DUMB else 0)
|
||||
|
||||
Reference in New Issue
Block a user