From b07924624ef29cff971565af59f8f125f087d529 Mon Sep 17 00:00:00 2001 From: Egor Ushakov Date: Tue, 4 Mar 2025 13:49:11 +0100 Subject: [PATCH] [debugger] fixing flaky tests GitOrigin-RevId: 6325d5f32e460156ad8fa4ab31275233a69903e5 --- .../engine/DebuggerManagerThreadImpl.kt | 5 ++- .../intellij/debugger/impl/InvokeThread.java | 37 ++++++++++++------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.kt b/java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.kt index 6592188a864b..b85f41874f89 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.kt +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.kt @@ -166,9 +166,10 @@ class DebuggerManagerThreadImpl @ApiStatus.Internal @JvmOverloads constructor( { if (currentCommand === myEvents.currentEvent) { // if current command is still in progress, cancel it - currentRequest.requestStop() + val request = currentRequest + request.requestStop() try { - currentRequest.join() + request.join() } catch (_: InterruptedException) { } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java b/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java index 5ada023b417b..f26020df1c89 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java @@ -118,7 +118,7 @@ public abstract class InvokeThread { protected final EventQueue myEvents; - private volatile WorkerThreadRequest myCurrentRequest = null; + private WorkerThreadRequest myCurrentRequest = null; public InvokeThread() { myEvents = new EventQueue<>(PrioritizedTask.Priority.values().length); @@ -128,15 +128,19 @@ public abstract class InvokeThread { protected abstract void processEvent(@NotNull E e); protected void startNewWorkerThread() { - assertCurrentThreadIsActive(); + // myCurrentRequest has to be updated atomically with calling setRequestFuture + // otherwise we may have asserts triggering inside workerRequest.requestStop etc. + synchronized (this) { + assertCurrentThreadIsActive(); - final WorkerThreadRequest workerRequest = new WorkerThreadRequest<>(this); - WorkerThreadRequest oldRequest = myCurrentRequest; // just for logging - myCurrentRequest = workerRequest; - if (LOG.isDebugEnabled()) { - LOG.debug("Started new worker thread request " + workerRequest + ", was " + oldRequest); + final WorkerThreadRequest workerRequest = new WorkerThreadRequest<>(this); + WorkerThreadRequest oldRequest = myCurrentRequest; // just for logging + myCurrentRequest = workerRequest; + if (LOG.isDebugEnabled()) { + LOG.debug("Started new worker thread request " + workerRequest + ", was " + oldRequest); + } + workerRequest.setRequestFuture(ApplicationManager.getApplication().executeOnPooledThread(workerRequest)); } - workerRequest.setRequestFuture(ApplicationManager.getApplication().executeOnPooledThread(workerRequest)); } protected static boolean assertCurrentThreadIsActive() { @@ -258,18 +262,23 @@ public abstract class InvokeThread { } protected void switchToRequest(WorkerThreadRequest newRequest) { - final WorkerThreadRequest currentThreadRequest = getCurrentThreadRequest(); - LOG.assertTrue(currentThreadRequest != null); - myCurrentRequest = newRequest; - if (LOG.isDebugEnabled()) { - LOG.debug("Switched current request from " + currentThreadRequest + " to " + newRequest); + WorkerThreadRequest currentThreadRequest; + synchronized (this) { + currentThreadRequest = getCurrentThreadRequest(); + LOG.assertTrue(currentThreadRequest != null); + myCurrentRequest = newRequest; + if (LOG.isDebugEnabled()) { + LOG.debug("Switched current request from " + currentThreadRequest + " to " + newRequest); + } } currentThreadRequest.requestStop(); } public WorkerThreadRequest getCurrentRequest() { - return myCurrentRequest; + synchronized (this) { + return myCurrentRequest; + } } public static WorkerThreadRequest getCurrentThreadRequest() {