diff options
author | Simeon Andreev | 2020-02-21 13:09:11 +0000 |
---|---|---|
committer | Andrey Loskutov | 2020-03-14 17:29:09 +0000 |
commit | aef281e1db65fd7b8e7525a0ac39de5ed54cb12b (patch) | |
tree | 3880165ad665ab5b4fc5287ae023bb9e8042eaad | |
parent | fdfddccb5c179ed07263229204d61818e85ae750 (diff) | |
download | eclipse.platform.debug-aef281e1db65fd7b8e7525a0ac39de5ed54cb12b.tar.gz eclipse.platform.debug-aef281e1db65fd7b8e7525a0ac39de5ed54cb12b.tar.xz eclipse.platform.debug-aef281e1db65fd7b8e7525a0ac39de5ed54cb12b.zip |
Bug 560348 - Wrong toolbar debug button state with two windowsI20200318-1100I20200317-1800I20200316-1800I20200315-2240I20200315-1800I20200314-1800
When debugging with 2 workbench windows, sometimes the main toolbar
debug buttons enabled state is incorrect. E.g. step over would be
disabled in 1 window, but not in the other window.
This is caused by job cancellation in
DebugCommandService.postUpdateCommand(). In particular, each window will
schedule an AbstractDebugCommand.UpdateJob per debug command (suspend,
resume, step over, etc.) and some of those jobs are cancelled by
postUpdateCommand(). A cancelled job can contain the action to update
for a specific window, in UpdateActionsRequest.fActions (stored in
AbstractDebugCommand.UpdateJob.request). The cancellation does not take
this into account, sometimes leading to wrong main toolbar debug button
states in either window.
This change disables the job cancellation if there are 2 or more
workbench windows.
In addition, the change moves cancellation to before new UpdateJobs are
triggered. This avoids cases in which updates triggered by a custom
debug context provider become cancelled, but newer updates only come
much later on from the Debug view context provider.
Change-Id: Ic9d4f87882982e745dfa4fb41f7ed0d856533566
Signed-off-by: Simeon Andreev <simeon.danailov.andreev@gmail.com>
-rw-r--r-- | org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/DebugCommandService.java | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/DebugCommandService.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/DebugCommandService.java index 2a8885796..8bfeda65f 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/DebugCommandService.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/DebugCommandService.java @@ -22,6 +22,7 @@ import java.util.Map.Entry; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.commands.IDebugCommandHandler; +import org.eclipse.debug.core.commands.IDebugCommandRequest; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.contexts.DebugContextEvent; import org.eclipse.debug.ui.contexts.IDebugContextListener; @@ -109,7 +110,9 @@ public class DebugCommandService implements IDebugContextListener { private void dispose() { fContextService.removeDebugContextListener(this); - fgServices.remove(fWindow); + synchronized (fgServices) { + fgServices.remove(fWindow); + } fCommandUpdates.clear(); fWindow = null; } @@ -122,7 +125,6 @@ public class DebugCommandService implements IDebugContextListener { */ public void postUpdateCommand(Class<?> commandType, IEnabledTarget action) { synchronized (fCommandUpdates) { - Job.getJobManager().cancel(commandType); List<IEnabledTarget> actions = fCommandUpdates.get(commandType); if (actions == null) { actions = new ArrayList<>(); @@ -177,6 +179,7 @@ public class DebugCommandService implements IDebugContextListener { * @param actions the actions to update */ private void updateCommand(Class<?> handlerType, Object[] elements, IEnabledTarget[] actions) { + cancelHandlerEnablementUpdateJobs(handlerType); if (elements.length == 1) { // usual case - one element Object element = elements[0]; @@ -272,4 +275,30 @@ public class DebugCommandService implements IDebugContextListener { return (IDebugCommandHandler)DebugPlugin.getAdapter(element, handlerType); } + /** + * Cancel handler enablement update jobs created in + * {@link org.eclipse.debug.core.commands.AbstractDebugCommand#canExecute(org.eclipse.debug.core.commands.IEnabledStateRequest)}. + * for the specified handler type. The debug command handler defines its type in + * {@link org.eclipse.debug.core.commands.AbstractDebugCommand#getEnabledStateJobFamily(IDebugCommandRequest)}. + * + * Does not cancel jobs if there are more than 2 workbench windows, since 1 + * window could cancel updates from another window, breaking some updates. See + * bug 560348. + * + * @param handlerType cancels enablement update jobs for this type of handler. + */ + private void cancelHandlerEnablementUpdateJobs(Class<?> handlerType) { + if (handlerType != null) { + boolean hasMultipleWindowServices = hasMultipleWindowServices(); + if (!hasMultipleWindowServices) { + Job.getJobManager().cancel(handlerType); + } + } + } + + private static boolean hasMultipleWindowServices() { + synchronized (fgServices) { + return fgServices.size() > 1; + } + } } |