Skip to content

Commit 23b8a04

Browse files
EcljpseB0Tjukzi
authored andcommitted
Console View: fix concurrency Issues
Running console did sometimes not show start infos transfered by Launch.fAttributes between threads eclipse-jdt/eclipse.jdt.debug#390
1 parent 71d63c4 commit 23b8a04

File tree

3 files changed

+41
-32
lines changed

3 files changed

+41
-32
lines changed

debug/org.eclipse.debug.core/core/org/eclipse/debug/core/Launch.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717

1818

1919
import java.util.ArrayList;
20-
import java.util.HashMap;
2120
import java.util.List;
21+
import java.util.Map;
22+
import java.util.Objects;
23+
import java.util.concurrent.ConcurrentHashMap;
2224
import java.util.concurrent.locks.Lock;
2325
import java.util.concurrent.locks.ReadWriteLock;
2426
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -66,7 +68,7 @@ public class Launch extends PlatformObject implements ILaunch, IDisconnect, ILau
6668
/**
6769
* The configuration that was launched, or null.
6870
*/
69-
private ILaunchConfiguration fConfiguration= null;
71+
private volatile ILaunchConfiguration fConfiguration = null;
7072

7173
/**
7274
* The system processes associated with
@@ -78,7 +80,7 @@ public class Launch extends PlatformObject implements ILaunch, IDisconnect, ILau
7880
* The source locator to use in the debug session
7981
* or <code>null</code> if not supported.
8082
*/
81-
private ISourceLocator fLocator= null;
83+
private volatile ISourceLocator fLocator = null;
8284

8385
/**
8486
* The mode this launch was launched in.
@@ -88,7 +90,7 @@ public class Launch extends PlatformObject implements ILaunch, IDisconnect, ILau
8890
/**
8991
* Table of client defined attributes
9092
*/
91-
private HashMap<String, String> fAttributes;
93+
private final Map<String, String> fAttributes = new ConcurrentHashMap<>();
9294

9395
/**
9496
* Flag indicating that change notification should
@@ -319,20 +321,20 @@ public ILaunchConfiguration getLaunchConfiguration() {
319321
*/
320322
@Override
321323
public void setAttribute(String key, String value) {
322-
if (fAttributes == null) {
323-
fAttributes = new HashMap<>(5);
324+
Objects.requireNonNull(key);
325+
if (value == null) {
326+
// ConcurrentHashMap does not allow null values
327+
fAttributes.remove(key);
328+
} else {
329+
fAttributes.put(key, value);
324330
}
325-
fAttributes.put(key, value);
326331
}
327332

328333
/**
329334
* @see ILaunch#getAttribute(String)
330335
*/
331336
@Override
332337
public String getAttribute(String key) {
333-
if (fAttributes == null) {
334-
return null;
335-
}
336338
return fAttributes.get(key);
337339
}
338340

@@ -343,7 +345,7 @@ public String getAttribute(String key) {
343345
public IDebugTarget[] getDebugTargets() {
344346
readLock.lock();
345347
try {
346-
return fTargets.toArray(new IDebugTarget[fTargets.size()]);
348+
return fTargets.toArray(IDebugTarget[]::new);
347349
} finally {
348350
readLock.unlock();
349351
}

debug/org.eclipse.debug.core/core/org/eclipse/debug/core/model/RuntimeProcess.java

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
import java.nio.charset.IllegalCharsetNameException;
1818
import java.nio.charset.UnsupportedCharsetException;
1919
import java.util.Collections;
20-
import java.util.HashMap;
2120
import java.util.List;
2221
import java.util.Map;
22+
import java.util.Objects;
23+
import java.util.concurrent.ConcurrentHashMap;
2324
import java.util.concurrent.ExecutionException;
2425
import java.util.concurrent.TimeUnit;
2526
import java.util.concurrent.TimeoutException;
@@ -68,7 +69,9 @@ public class RuntimeProcess extends PlatformObject implements IProcess {
6869
private Process fProcess;
6970

7071
/**
71-
* This process's exit value
72+
* This process's exit value.
73+
*
74+
* synchronized by this
7275
*/
7376
private int fExitValue;
7477

@@ -96,17 +99,17 @@ public class RuntimeProcess extends PlatformObject implements IProcess {
9699
/**
97100
* Table of client defined attributes
98101
*/
99-
private Map<String, String> fAttributes;
102+
private final Map<String, String> fAttributes = new ConcurrentHashMap<>();
100103

101104
/**
102105
* Whether output from the process should be captured or swallowed
103106
*/
104-
private boolean fCaptureOutput = true;
107+
private final boolean fCaptureOutput;
105108

106109
/**
107110
* Whether the descendants of this process should be terminated too
108111
*/
109-
private boolean fTerminateDescendants = true;
112+
private final boolean fTerminateDescendants;
110113

111114
private final String fThreadNameSuffix;
112115

@@ -141,14 +144,16 @@ public RuntimeProcess(ILaunch launch, Process process, String name, Map<String,
141144
String captureOutput = launch.getAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT);
142145
fCaptureOutput = !("false".equals(captureOutput)); //$NON-NLS-1$
143146

147+
boolean terminateDescendants = true;
144148
try {
145149
ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration();
146150
if (launchConfiguration != null) {
147-
fTerminateDescendants = launchConfiguration.getAttribute(DebugPlugin.ATTR_TERMINATE_DESCENDANTS, true);
151+
terminateDescendants = launchConfiguration.getAttribute(DebugPlugin.ATTR_TERMINATE_DESCENDANTS, true);
148152
}
149153
} catch (CoreException e) {
150154
DebugPlugin.log(e);
151155
}
156+
fTerminateDescendants = terminateDescendants;
152157
fThreadNameSuffix = getPidInfo(process, launch);
153158

154159
fStreamsProxy = createStreamsProxy();
@@ -264,7 +269,9 @@ public void terminate() throws DebugException {
264269
try { // (in total don't wait longer than TERMINATION_TIMEOUT)
265270
long waitStart = System.currentTimeMillis();
266271
if (process.waitFor(TERMINATION_TIMEOUT, TimeUnit.MILLISECONDS)) {
267-
fExitValue = process.exitValue();
272+
synchronized (this) {
273+
fExitValue = process.exitValue();
274+
}
268275
if (waitFor(descendants, waitStart)) {
269276
return;
270277
}
@@ -419,26 +426,25 @@ protected void fireChangeEvent() {
419426
*/
420427
@Override
421428
public void setAttribute(String key, String value) {
422-
if (fAttributes == null) {
423-
fAttributes = new HashMap<>(5);
424-
}
425-
Object origVal = fAttributes.get(key);
426-
if (origVal != null && origVal.equals(value)) {
427-
return; //nothing changed.
429+
Objects.requireNonNull(key);
430+
if (value == null) {
431+
// ConcurrentHashMap does not allow null values
432+
if (fAttributes.remove(key) != null) {
433+
fireChangeEvent();
434+
}
435+
} else {
436+
String origVal = fAttributes.put(key, value);
437+
if (!Objects.equals(origVal, value)) {
438+
fireChangeEvent();
439+
}
428440
}
429-
430-
fAttributes.put(key, value);
431-
fireChangeEvent();
432441
}
433442

434443
/**
435444
* @see IProcess#getAttribute(String)
436445
*/
437446
@Override
438447
public String getAttribute(String key) {
439-
if (fAttributes == null) {
440-
return null;
441-
}
442448
return fAttributes.get(key);
443449
}
444450

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,6 @@ public ProcessConsole(IProcess process, IConsoleColorProvider colorProvider, Str
248248

249249
colorProvider.connect(fProcess, this);
250250

251-
setName(computeName());
252-
253251
Color color = fColorProvider.getColor(IDebugUIConstants.ID_STANDARD_INPUT_STREAM);
254252
if (fInput instanceof IOConsoleInputStream) {
255253
((IOConsoleInputStream)fInput).setColor(color);
@@ -556,6 +554,9 @@ private synchronized void disposeStreams() {
556554
protected void init() {
557555
super.init();
558556
DebugPlugin.getDefault().addDebugEventListener(this);
557+
// computeName() after addDebugEventListener()
558+
// see https://github.com/eclipse-jdt/eclipse.jdt.debug/issues/390
559+
setName(computeName());
559560
if (fProcess.isTerminated()) {
560561
closeStreams();
561562
resetName();

0 commit comments

Comments
 (0)