mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[threading] RUBY-34356: Throw PCE if lock acquisition was promptly canceled in blocking context
GitOrigin-RevId: dd0b5331b316033255115dc3ba65785ca3f534ba
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d0a4e16b0b
commit
881963a0a8
@@ -8,6 +8,7 @@ import com.intellij.core.rwmutex.*
|
||||
import com.intellij.openapi.application.*
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.progress.Cancellation
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.platform.locking.impl.listeners.ErrorHandler
|
||||
import com.intellij.platform.locking.impl.listeners.LegacyProgressIndicatorProvider
|
||||
@@ -925,8 +926,16 @@ class NestedLocksThreadingSupport : ThreadingSupport {
|
||||
finally {
|
||||
writeLockInitResult.release()
|
||||
}
|
||||
} catch (e : Throwable) {
|
||||
throw e
|
||||
}
|
||||
catch (e: CancellationException) {
|
||||
val job = currentThreadContext()[Job]
|
||||
if (job != null && job.isCancelled && e !is ProcessCanceledException) {
|
||||
// the lock acquisition was promptly canceled, so we need to rethrow a PCE from here to comply with blocking context
|
||||
throw ProcessCanceledException(e)
|
||||
}
|
||||
else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
finally {
|
||||
writeIntentInitResult.release()
|
||||
|
||||
+32
@@ -15,6 +15,7 @@ import com.intellij.openapi.application.impl.assertReferenced
|
||||
import com.intellij.openapi.application.impl.pumpEDT
|
||||
import com.intellij.openapi.application.impl.withModality
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.progress.*
|
||||
import com.intellij.openapi.util.Condition
|
||||
import com.intellij.openapi.util.Conditions
|
||||
@@ -28,6 +29,7 @@ import com.intellij.util.application
|
||||
import com.intellij.util.getValue
|
||||
import com.intellij.util.setValue
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.future.asCompletableFuture
|
||||
import org.jetbrains.concurrency.AsyncPromise
|
||||
import org.jetbrains.concurrency.asCancellablePromise
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
@@ -873,6 +875,36 @@ class CancellationPropagationTest {
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invokeAndWait propagates cancellation 2`(): Unit = timeoutRunBlocking(context = Dispatchers.Default) {
|
||||
val job1 = Job(coroutineContext.job)
|
||||
val job2 = Job(coroutineContext.job)
|
||||
val job3 = Job(coroutineContext.job)
|
||||
launch {
|
||||
readAction {
|
||||
job1.complete()
|
||||
job2.asCompletableFuture().join()
|
||||
}
|
||||
}
|
||||
job1.join()
|
||||
val job = launch(Dispatchers.Default) {
|
||||
blockingContext {
|
||||
application.invokeAndWait {
|
||||
job3.complete()
|
||||
runWriteAction {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
job3.join()
|
||||
delay(100)
|
||||
job.cancelAndJoin()
|
||||
job2.cancelAndJoin()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
fun `coroutine non-cancellable section coherence`() = timeoutRunBlocking {
|
||||
withContext(Dispatchers.Default) {
|
||||
|
||||
Reference in New Issue
Block a user