[threading] IJPL-196063: Restrict public write-intent read action to EDT only

GitOrigin-RevId: 53651d38693d4850b5c146949f6d0db30f0f318a
This commit is contained in:
Konstantin Nisht
2025-07-09 19:34:26 +00:00
committed by intellij-monorepo-bot
parent ee46a78b92
commit 954b15c2d2
2 changed files with 14 additions and 6 deletions
@@ -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 <T> backgroundWriteAction(action: () -> T): T {
*/
@Experimental
suspend fun <T> 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)
@@ -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)
}
}
}