diff options
author | Markus Duft | 2017-08-07 13:55:38 +0000 |
---|---|---|
committer | Markus Duft | 2017-08-07 13:55:38 +0000 |
commit | 1ac7a50083b25934db5e4902343c7a186435763b (patch) | |
tree | c507b31e7e5885a920e7b6685e78c02beea54d5a /org.eclipse.debug.core | |
parent | 8df4ce30969f1cca45747373252de64a5077c840 (diff) | |
download | eclipse.platform.debug-1ac7a50083b25934db5e4902343c7a186435763b.tar.gz eclipse.platform.debug-1ac7a50083b25934db5e4902343c7a186435763b.tar.xz eclipse.platform.debug-1ac7a50083b25934db5e4902343c7a186435763b.zip |
Bug 520273 - synchronize access to group subLaunchesI20170906-0225
This fix makes sure that concurrent access to the subLaunches of a group
cannot cause Exceptions - e.g. while terminating a launch group.
Change-Id: I4e009b41b4acaa6104c2c53159e34c7f95841dbe
Signed-off-by: Markus Duft <markus.duft@ssi-schaefer.com>
Diffstat (limited to 'org.eclipse.debug.core')
-rw-r--r-- | org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunch.java | 123 |
1 files changed, 69 insertions, 54 deletions
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunch.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunch.java index e611a4686..d46953cf4 100644 --- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunch.java +++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunch.java @@ -46,8 +46,8 @@ public class GroupLaunch extends Launch implements ILaunchesListener2 { private boolean fLaunched = false; /** - * A map of all our sub-launches and the current processes that belong - * to each one. + * A map of all our sub-launches and the current processes that belong to + * each one. */ private Map<ILaunch, IProcess[]> subLaunches = new HashMap<ILaunch, IProcess[]>(); @@ -66,21 +66,25 @@ public class GroupLaunch extends Launch implements ILaunchesListener2 { * @param subLaunch */ public void addSubLaunch(ILaunch subLaunch) { - subLaunches.put(subLaunch, new IProcess[] {}); + synchronized (subLaunches) { + subLaunches.put(subLaunch, new IProcess[] {}); + } } private boolean isChild(ILaunch launch) { - for (ILaunch subLaunch : subLaunches.keySet()) { - if (subLaunch == launch) { - return true; + synchronized (subLaunches) { + for (ILaunch subLaunch : subLaunches.keySet()) { + if (subLaunch == launch) { + return true; + } } + return false; } - return false; } /** - * Override default behavior by querying all sub-launches to see if they - * are terminated + * Override default behavior by querying all sub-launches to see if they are + * terminated * * @see org.eclipse.debug.core.Launch#isTerminated() */ @@ -90,14 +94,16 @@ public class GroupLaunch extends Launch implements ILaunchesListener2 { return true; } - if (subLaunches.size() == 0) { - return fLaunched; // in case we're done launching and there is - // nobody -> terminated - } + synchronized (subLaunches) { + if (subLaunches.size() == 0) { + return fLaunched; // in case we're done launching and there is + // nobody -> terminated + } - for (ILaunch launch : subLaunches.keySet()) { - if (!launch.isTerminated()) { - return false; + for (ILaunch launch : subLaunches.keySet()) { + if (!launch.isTerminated()) { + return false; + } } } return fLaunched; // we're done only if we're already done launching. @@ -113,16 +119,18 @@ public class GroupLaunch extends Launch implements ILaunchesListener2 { */ @Override public boolean canTerminate() { - if (subLaunches.size() == 0) { - return false; - } + synchronized (subLaunches) { + if (subLaunches.size() == 0) { + return false; + } - for (ILaunch launch : subLaunches.keySet()) { - if (launch.canTerminate()) { - return true; + for (ILaunch launch : subLaunches.keySet()) { + if (launch.canTerminate()) { + return true; + } } + return false; } - return false; } /** @@ -139,12 +147,14 @@ public class GroupLaunch extends Launch implements ILaunchesListener2 { // group when children disappear even if launching has not finished yet. markLaunched(); - for (ILaunch launch : subLaunches.keySet()) { - if (launch.canTerminate()) { - try { - launch.terminate(); - } catch (DebugException e) { - status.merge(e.getStatus()); + synchronized (subLaunches) { + for (ILaunch launch : subLaunches.keySet()) { + if (launch.canTerminate()) { + try { + launch.terminate(); + } catch (DebugException e) { + status.merge(e.getStatus()); + } } } } @@ -171,13 +181,16 @@ public class GroupLaunch extends Launch implements ILaunchesListener2 { return; } - // Remove sub launch, keeping the processes of the terminated launch - // to show the association and to keep the console content accessible - if (subLaunches.remove(launch) != null) { - // terminate ourselves if this is the last sub launch - if (subLaunches.size() == 0 && fLaunched) { - fTerminated = true; - fireTerminate(); + synchronized (subLaunches) { + // Remove sub launch, keeping the processes of the terminated launch + // to show the association and to keep the console content + // accessible + if (subLaunches.remove(launch) != null) { + // terminate ourselves if this is the last sub launch + if (subLaunches.size() == 0 && fLaunched) { + fTerminated = true; + fireTerminate(); + } } } } @@ -188,25 +201,27 @@ public class GroupLaunch extends Launch implements ILaunchesListener2 { return; } - // add/remove processes - if (isChild(launch)) { - // Remove old processes - IProcess[] oldProcesses = subLaunches.get(launch); - IProcess[] newProcesses = launch.getProcesses(); - - // avoid notifications when processes have not changed. - if (!Arrays.equals(oldProcesses, newProcesses)) { - for (IProcess oldProcess : oldProcesses) { - removeProcess(oldProcess); - } - - // Add new processes - for (IProcess newProcess : newProcesses) { - addProcess(newProcess); + synchronized (subLaunches) { + // add/remove processes + if (isChild(launch)) { + // Remove old processes + IProcess[] oldProcesses = subLaunches.get(launch); + IProcess[] newProcesses = launch.getProcesses(); + + // avoid notifications when processes have not changed. + if (!Arrays.equals(oldProcesses, newProcesses)) { + for (IProcess oldProcess : oldProcesses) { + removeProcess(oldProcess); + } + + // Add new processes + for (IProcess newProcess : newProcesses) { + addProcess(newProcess); + } + + // Replace the processes of the changed launch + subLaunches.put(launch, newProcesses); } - - // Replace the processes of the changed launch - subLaunches.put(launch, newProcesses); } } } |