mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 06:50:54 +07:00
[platform] IJ-CR-152034 QD-10403: Cleanup canceled invokeLater
(cherry picked from commit 970a71bb513fcd2029bff2f237a342c4737fb779) GitOrigin-RevId: 50865014a604a94de21938b9f2d8b6fc635fc0f7
This commit is contained in:
committed by
intellij-monorepo-bot
parent
363e9973c0
commit
d173a80534
@@ -11,6 +11,7 @@ import com.intellij.platform.ide.progress.TaskCancellation
|
||||
import com.intellij.testFramework.common.timeoutRunBlocking
|
||||
import com.intellij.testFramework.junit5.SystemProperty
|
||||
import com.intellij.testFramework.junit5.TestApplication
|
||||
import com.intellij.util.application
|
||||
import com.intellij.util.getValue
|
||||
import com.intellij.util.setValue
|
||||
import kotlinx.coroutines.*
|
||||
@@ -350,4 +351,17 @@ class ThreadContextPropagationTest {
|
||||
}
|
||||
Assertions.assertTrue(tracker.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cancellation of invokeLater triggers cleanup events`() = timeoutRunBlocking {
|
||||
val tracker = AtomicBoolean(false)
|
||||
val expiration = AtomicBoolean(false)
|
||||
withContext(Dispatchers.EDT + MyIjElement(tracker)) {
|
||||
@Suppress("ForbiddenInSuspectContextMethod")
|
||||
application.invokeLater({ Assertions.fail() }, { expiration.get() })
|
||||
expiration.set(true)
|
||||
}
|
||||
delay(100)
|
||||
Assertions.assertTrue(tracker.get())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,10 +338,8 @@ fun capturePropagationContext(r: Runnable, expired: Condition<*>, signalRunnable
|
||||
var expired = expired
|
||||
command = ContextRunnable(childContext, command)
|
||||
val cont = childContext.continuation
|
||||
if (cont != null) {
|
||||
val childJob = cont.context.job
|
||||
expired = cancelIfExpired(expired, childJob)
|
||||
}
|
||||
val childJob = cont?.context?.job
|
||||
expired = cleanupIfExpired(expired, childContext, childJob)
|
||||
return JBPair.create(command, expired)
|
||||
}
|
||||
|
||||
@@ -353,17 +351,18 @@ fun <T, U> captureBiConsumerThreadContext(f: BiConsumer<T, U>): BiConsumer<T, U>
|
||||
return f
|
||||
}
|
||||
|
||||
private fun <T> cancelIfExpired(expiredCondition: Condition<in T>, childJob: Job): Condition<T> {
|
||||
private fun <T> cleanupIfExpired(expiredCondition: Condition<in T>, childContext: ChildContext, childJob: Job?): Condition<T> {
|
||||
return Condition { t: T ->
|
||||
val expired = expiredCondition.value(t)
|
||||
if (expired) {
|
||||
// Cancel to avoid a hanging child job which will prevent completion of the parent one.
|
||||
childJob.cancel(null)
|
||||
childJob?.cancel(null)
|
||||
childContext.applyContextActions(false).finish()
|
||||
true
|
||||
}
|
||||
else {
|
||||
// Treat runnable as expired if its job was already cancelled.
|
||||
childJob.isCancelled
|
||||
childJob?.isCancelled == true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user