[threading] IJPL-206769: Prepare tests for NonBlockingFlushQueue

GitOrigin-RevId: b756dd73cc2f24aa6a5bc7f6047827eba240006b
This commit is contained in:
Konstantin Nisht
2025-10-06 09:27:45 +00:00
committed by intellij-monorepo-bot
parent 4c13774283
commit fc46acb7e7
5 changed files with 18 additions and 9 deletions
@@ -268,7 +268,6 @@ class DocumentCommitThread : DocumentCommitProcessor, Disposable {
while (!boundedTaskExecutor.isEmpty || commitInProgressCounter.get() > 0) {
try {
boundedTaskExecutor.waitAllTasksExecuted(10, TimeUnit.MILLISECONDS)
Thread.sleep(10)
}
catch (e: TimeoutException) {
if (System.nanoTime() > deadLine) {
@@ -602,7 +602,10 @@ class NestedLocksThreadingSupport : ThreadingSupport {
// In short, we apply the parallelization of write-intent lock here with downgrading of write permits back to write intent.
val token = downgradeWriteLockToWriteIntent()
val (newState, cleanup) = currentComputationState.parallelizeWriteIntent(thisLevelPermit.get() as WriteIntentPermit)
statesOfWIThread.set(statesOfWIThread.get() ?: mutableListOf())
statesOfWIThread.get()?.add(newState)
return ComputationStateContextElement(newState) to {
statesOfWIThread.get()?.removeLast()
cleanup.finish()
token.finish()
}
@@ -684,12 +684,12 @@ public class LaterInvocatorTest extends HeavyPlatformTestCase {
LaterInvocator.enterModal("some object");
UIUtil.dispatchAllInvocationEvents();
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue();
assertFalse(invoked.get());
LaterInvocator.enterModal(myModalDialog);
UIUtil.dispatchAllInvocationEvents();
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue();
assertTrue(invoked.get());
});
}
@@ -711,11 +711,11 @@ public class LaterInvocatorTest extends HeavyPlatformTestCase {
ApplicationManager.getApplication().invokeLater(() -> invoked.set(true), ModalityState.nonModal());
LaterInvocator.enterModal(myWindow1);
UIUtil.dispatchAllInvocationEvents();
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue();
assertFalse(invoked.get());
LaterInvocator.markTransparent(ModalityState.current());
UIUtil.dispatchAllInvocationEvents();
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue();
assertTrue(invoked.get());
});
}
@@ -9,7 +9,6 @@ import com.intellij.testFramework.common.timeoutRunBlocking
import com.intellij.testFramework.junit5.RegistryKey
import com.intellij.testFramework.junit5.TestApplication
import com.intellij.testFramework.junit5.TestDisposable
import com.intellij.util.application
import kotlinx.coroutines.*
import kotlinx.coroutines.future.asCompletableFuture
import org.assertj.core.api.Assertions.assertThat
@@ -47,8 +46,10 @@ class SuvorovProgressTest {
val edtActionCompleted = Job(coroutineContext.job)
launch {
backgroundWriteAction {
application.invokeLater {
edtActionCompleted.complete()
launch(Dispatchers.UiWithModelAccess) {
WriteIntentReadAction.run {
edtActionCompleted.complete()
}
}
writeActionMayFinish.asCompletableFuture().join()
}
@@ -469,6 +469,7 @@ public final class PlatformTestUtil {
AtomicBoolean laterInvoked = new AtomicBoolean();
app.invokeLater(() -> laterInvoked.set(true));
dispatchAllInvocationEventsInIdeEventQueue();
waitForAllDocumentsCommitted(10, TimeUnit.SECONDS);
assertTrue(laterInvoked.get());
TimeoutUtil.sleep(sleptAlready ? 10 : delay);
@@ -506,9 +507,14 @@ public final class PlatformTestUtil {
IdeEventQueue eventQueue = IdeEventQueue.getInstance();
ThreadContext.resetThreadContext(() -> {
TestOnlyThreading.releaseTheAcquiredWriteIntentLockThenExecuteActionAndTakeWriteIntentLockBack(() -> {
// due to non-blocking acquisition of write-intent, `NonBlockingFlushQueue` can appear in the state
// where it has stuck WI runnables. This method is called to ensure that _all_ runnables are dispatched,
// so we also want to wait for WI runnables here
AtomicBoolean canary = new AtomicBoolean(false);
ApplicationManager.getApplication().invokeLater(() -> canary.set(true), ModalityState.any());
while (true) {
AWTEvent event = eventQueue.peekEvent();
if (event == null) break;
if (event == null && canary.get()) break;
event = eventQueue.getNextEvent();
if (event instanceof InvocationEvent) {
eventQueue.dispatchEvent(event);