Skip to content

Commit 16c60c8

Browse files
committed
Don't use display thread for scheduling console update tasks
This fixes regression from 7e1f60c, where main thread (which owns lock on UI operations) waits for the lock on ProcessConsole to update console name but never gets it because console code is blocked internally waiting for a QueueProcessingJob being executed on UI thread. The solution is to avoid direct calls from UI to ProcessConsole.resetName(). Fixes #2460
1 parent 8594fad commit 16c60c8

1 file changed

Lines changed: 21 additions & 4 deletions

File tree

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/console/ProcessConsole.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
import java.util.ArrayList;
3838
import java.util.Date;
3939
import java.util.List;
40+
import java.util.concurrent.Executors;
41+
import java.util.concurrent.ScheduledExecutorService;
42+
import java.util.concurrent.ScheduledFuture;
43+
import java.util.concurrent.TimeUnit;
4044
import java.util.regex.Pattern;
4145

4246
import org.eclipse.core.resources.IFile;
@@ -139,6 +143,9 @@ public class ProcessConsole extends IOConsole implements IConsole, IDebugEventSe
139143

140144
private volatile boolean fStreamsClosed;
141145

146+
private final ScheduledExecutorService consoleNameUpdateExecutor;
147+
private volatile ScheduledFuture<?> pendingNameUpdate;
148+
142149
/**
143150
* Create process console with default encoding.
144151
*
@@ -160,7 +167,11 @@ public ProcessConsole(IProcess process, IConsoleColorProvider colorProvider, Str
160167
super(IInternalDebugCoreConstants.EMPTY_STRING, IDebugUIConstants.ID_PROCESS_CONSOLE_TYPE, null, encoding, true);
161168
fProcess = process;
162169
fUserInput = getInputStream();
163-
170+
consoleNameUpdateExecutor = Executors.newSingleThreadScheduledExecutor(r -> {
171+
Thread t = new Thread(r, "Console name updater"); //$NON-NLS-1$
172+
t.setDaemon(true);
173+
return t;
174+
});
164175
ILaunchConfiguration configuration = process.getLaunch().getLaunchConfiguration();
165176
String file = null;
166177
boolean append = false;
@@ -349,9 +360,14 @@ protected String computeName() {
349360
DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
350361
String elapsedFormat = "%d:%02d:%02d.%03d"; //$NON-NLS-1$
351362
if (terminateTime == null) {
352-
// refresh every second:
353-
DebugUIPlugin.getStandardDisplay().asyncExec(
354-
() -> DebugUIPlugin.getStandardDisplay().timerExec(1000, () -> resetName(false)));
363+
// refresh every second, but only if not already scheduled:
364+
ScheduledFuture<?> currentPending = pendingNameUpdate;
365+
if (currentPending == null || currentPending.isDone()) {
366+
currentPending = consoleNameUpdateExecutor.schedule(() -> {
367+
pendingNameUpdate = null;
368+
resetName(false);
369+
}, 1, TimeUnit.SECONDS);
370+
}
355371
// pointless to update milliseconds:
356372
elapsedFormat = "%d:%02d:%02d"; //$NON-NLS-1$
357373
}
@@ -531,6 +547,7 @@ public IProcess getProcess() {
531547
protected void dispose() {
532548
super.dispose();
533549
fColorProvider.disconnect();
550+
consoleNameUpdateExecutor.shutdownNow();
534551
DebugPlugin.getDefault().removeDebugEventListener(this);
535552
DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
536553
JFaceResources.getFontRegistry().removeListener(this);

0 commit comments

Comments
 (0)