|
17 | 17 | import java.nio.charset.IllegalCharsetNameException;
|
18 | 18 | import java.nio.charset.UnsupportedCharsetException;
|
19 | 19 | import java.util.Collections;
|
20 |
| -import java.util.HashMap; |
21 | 20 | import java.util.List;
|
22 | 21 | import java.util.Map;
|
| 22 | +import java.util.Objects; |
| 23 | +import java.util.concurrent.ConcurrentHashMap; |
23 | 24 | import java.util.concurrent.ExecutionException;
|
24 | 25 | import java.util.concurrent.TimeUnit;
|
25 | 26 | import java.util.concurrent.TimeoutException;
|
@@ -68,7 +69,9 @@ public class RuntimeProcess extends PlatformObject implements IProcess {
|
68 | 69 | private Process fProcess;
|
69 | 70 |
|
70 | 71 | /**
|
71 |
| - * This process's exit value |
| 72 | + * This process's exit value. |
| 73 | + * |
| 74 | + * synchronized by this |
72 | 75 | */
|
73 | 76 | private int fExitValue;
|
74 | 77 |
|
@@ -96,17 +99,17 @@ public class RuntimeProcess extends PlatformObject implements IProcess {
|
96 | 99 | /**
|
97 | 100 | * Table of client defined attributes
|
98 | 101 | */
|
99 |
| - private Map<String, String> fAttributes; |
| 102 | + private final Map<String, String> fAttributes = new ConcurrentHashMap<>(); |
100 | 103 |
|
101 | 104 | /**
|
102 | 105 | * Whether output from the process should be captured or swallowed
|
103 | 106 | */
|
104 |
| - private boolean fCaptureOutput = true; |
| 107 | + private final boolean fCaptureOutput; |
105 | 108 |
|
106 | 109 | /**
|
107 | 110 | * Whether the descendants of this process should be terminated too
|
108 | 111 | */
|
109 |
| - private boolean fTerminateDescendants = true; |
| 112 | + private final boolean fTerminateDescendants; |
110 | 113 |
|
111 | 114 | private final String fThreadNameSuffix;
|
112 | 115 |
|
@@ -141,14 +144,16 @@ public RuntimeProcess(ILaunch launch, Process process, String name, Map<String,
|
141 | 144 | String captureOutput = launch.getAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT);
|
142 | 145 | fCaptureOutput = !("false".equals(captureOutput)); //$NON-NLS-1$
|
143 | 146 |
|
| 147 | + boolean terminateDescendants = true; |
144 | 148 | try {
|
145 | 149 | ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration();
|
146 | 150 | if (launchConfiguration != null) {
|
147 |
| - fTerminateDescendants = launchConfiguration.getAttribute(DebugPlugin.ATTR_TERMINATE_DESCENDANTS, true); |
| 151 | + terminateDescendants = launchConfiguration.getAttribute(DebugPlugin.ATTR_TERMINATE_DESCENDANTS, true); |
148 | 152 | }
|
149 | 153 | } catch (CoreException e) {
|
150 | 154 | DebugPlugin.log(e);
|
151 | 155 | }
|
| 156 | + fTerminateDescendants = terminateDescendants; |
152 | 157 | fThreadNameSuffix = getPidInfo(process, launch);
|
153 | 158 |
|
154 | 159 | fStreamsProxy = createStreamsProxy();
|
@@ -264,7 +269,9 @@ public void terminate() throws DebugException {
|
264 | 269 | try { // (in total don't wait longer than TERMINATION_TIMEOUT)
|
265 | 270 | long waitStart = System.currentTimeMillis();
|
266 | 271 | if (process.waitFor(TERMINATION_TIMEOUT, TimeUnit.MILLISECONDS)) {
|
267 |
| - fExitValue = process.exitValue(); |
| 272 | + synchronized (this) { |
| 273 | + fExitValue = process.exitValue(); |
| 274 | + } |
268 | 275 | if (waitFor(descendants, waitStart)) {
|
269 | 276 | return;
|
270 | 277 | }
|
@@ -419,26 +426,25 @@ protected void fireChangeEvent() {
|
419 | 426 | */
|
420 | 427 | @Override
|
421 | 428 | 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 | + } |
428 | 440 | }
|
429 |
| - |
430 |
| - fAttributes.put(key, value); |
431 |
| - fireChangeEvent(); |
432 | 441 | }
|
433 | 442 |
|
434 | 443 | /**
|
435 | 444 | * @see IProcess#getAttribute(String)
|
436 | 445 | */
|
437 | 446 | @Override
|
438 | 447 | public String getAttribute(String key) {
|
439 |
| - if (fAttributes == null) { |
440 |
| - return null; |
441 |
| - } |
442 | 448 | return fAttributes.get(key);
|
443 | 449 | }
|
444 | 450 |
|
|
0 commit comments