Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimeon Andreev2020-02-21 13:09:11 +0000
committerAndrey Loskutov2020-03-14 17:29:09 +0000
commitaef281e1db65fd7b8e7525a0ac39de5ed54cb12b (patch)
tree3880165ad665ab5b4fc5287ae023bb9e8042eaad
parentfdfddccb5c179ed07263229204d61818e85ae750 (diff)
downloadeclipse.platform.debug-aef281e1db65fd7b8e7525a0ac39de5ed54cb12b.tar.gz
eclipse.platform.debug-aef281e1db65fd7b8e7525a0ac39de5ed54cb12b.tar.xz
eclipse.platform.debug-aef281e1db65fd7b8e7525a0ac39de5ed54cb12b.zip
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.java33
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;
+ }
+ }
}

Back to the top