From 954b15c2d2b1dd7c1433730b1feaf12e5a683cfa Mon Sep 17 00:00:00 2001 From: Konstantin Nisht Date: Mon, 7 Jul 2025 18:00:04 +0200 Subject: [PATCH] [threading] IJPL-196063: Restrict public write-intent read action to EDT only GitOrigin-RevId: 53651d38693d4850b5c146949f6d0db30f0f318a --- .../src/com/intellij/openapi/application/coroutines.kt | 10 +++++++++- .../progress/RunWithModalProgressBlockingTest.kt | 10 +++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/platform/core-api/src/com/intellij/openapi/application/coroutines.kt b/platform/core-api/src/com/intellij/openapi/application/coroutines.kt index 6415da896ad6..b9d5d445d0e6 100644 --- a/platform/core-api/src/com/intellij/openapi/application/coroutines.kt +++ b/platform/core-api/src/com/intellij/openapi/application/coroutines.kt @@ -6,6 +6,7 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.util.Computable import com.intellij.openapi.util.IntellijInternalApi import com.intellij.openapi.util.ThrowableComputable +import com.intellij.util.ui.EDT import kotlinx.coroutines.* import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.ApiStatus.Experimental @@ -304,7 +305,14 @@ suspend fun backgroundWriteAction(action: () -> T): T { */ @Experimental suspend fun writeIntentReadAction(action: () -> T): T { - return ApplicationManager.getApplication().runWriteIntentReadAction(ThrowableComputable(action)) + if (EDT.isCurrentThreadEdt()) { + return ApplicationManager.getApplication().runWriteIntentReadAction(ThrowableComputable(action)) + } + else { + return withContext(Dispatchers.EDT) { + action() + } + } } private fun readWriteActionSupport() = ApplicationManager.getApplication().getService(ReadWriteActionSupport::class.java) diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/progress/RunWithModalProgressBlockingTest.kt b/platform/platform-tests/testSrc/com/intellij/openapi/progress/RunWithModalProgressBlockingTest.kt index dedaa6053d02..2f5740a3b3a9 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/progress/RunWithModalProgressBlockingTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/openapi/progress/RunWithModalProgressBlockingTest.kt @@ -391,16 +391,16 @@ class RunWithModalProgressBlockingTest : ModalCoroutineTest() { @Suppress("ForbiddenInSuspectContextMethod") @Test - fun `simultaneous wa and wira are forbidden`(): Unit = runBlocking(Dispatchers.EDT) { + fun `simultaneous wa and wira are forbidden`(): Unit = timeoutRunBlocking(context = Dispatchers.EDT) { val writeActionCounter = AtomicInteger(0) writeIntentReadAction { runWithModalProgressBlocking { - repeat(Runtime.getRuntime().availableProcessors() * 5) { + repeat(200) { launch(Dispatchers.Default) { backgroundWriteAction { try { writeActionCounter.incrementAndGet() - Thread.sleep(100) + Thread.sleep(10) } finally { writeActionCounter.decrementAndGet() @@ -408,11 +408,11 @@ class RunWithModalProgressBlockingTest : ModalCoroutineTest() { } } } - repeat(Runtime.getRuntime().availableProcessors() * 5) { + repeat(100) { launch(Dispatchers.Default) { writeIntentReadAction { assertEquals(0, writeActionCounter.get()) - Thread.sleep(100) + Thread.sleep(10) } } }