From 4f8e498fa7af12c9d1d0ab48e366f62a9dadcbeb Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Thu, 6 Dec 2012 14:07:51 -0800 Subject: [PATCH] Bug 386175 - all threads that have ever been displayed get refreshed on suspend Change-Id: I3b1e842e8dd82463fe2cc35bcbdb0e52ae16baef Signed-off-by: Pawel Piech Reviewed-on: https://git.eclipse.org/r/9088 Reviewed-by: Marc Khouzam IP-Clean: Marc Khouzam Tested-by: Marc Khouzam --- .../launch/AbstractContainerVMNode.java | 70 ++++++++++++++++++- .../launch/AbstractLaunchVMProvider.java | 7 +- .../launch/FullStackRefreshEvent.java | 14 +++- .../viewmodel/launch/StackFramesVMNode.java | 17 +++-- 4 files changed, 98 insertions(+), 10 deletions(-) diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractContainerVMNode.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractContainerVMNode.java index 13b398fbcfa..430b3f0f759 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractContainerVMNode.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractContainerVMNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2011 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2013 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -302,7 +302,10 @@ public abstract class AbstractContainerVMNode extends AbstractExecutionContextVM return IModelDelta.SELECT | IModelDelta.EXPAND; } else if (e instanceof StateChangedEvent) { return IModelDelta.STATE; - } + } else if (e instanceof FullStackRefreshEvent && + (((FullStackRefreshEvent)e).getTriggeringEvent() instanceof IContainerSuspendedDMEvent)) { + return IModelDelta.CONTENT; + } return IModelDelta.NO_CHANGE; } @@ -389,9 +392,72 @@ public abstract class AbstractContainerVMNode extends AbstractExecutionContextVM // If there is a state change needed on the container, update the container if (dmc instanceof IContainerDMContext) parentDelta.addNode(createVMContext(dmc), IModelDelta.STATE); + } else if (e instanceof FullStackRefreshEvent) { + FullStackRefreshEvent refreshEvent = (FullStackRefreshEvent)e; + if (refreshEvent.getTriggeringEvent() instanceof IContainerSuspendedDMEvent) { + // For a full container suspended event, issue a single change when we get + // a FullStackRefreshEvent. This avoids refreshing all threads, even those + // there are not visible + // bug 386175 + IContainerSuspendedDMEvent containerTriggerEvent = + (IContainerSuspendedDMEvent)refreshEvent.getTriggeringEvent(); + buildDeltaForFullStackRefreshEvent((IContainerDMContext)refreshEvent.getDMContext(), + containerTriggerEvent.getTriggeringContexts(), parentDelta, nodeOffset, requestMonitor); + return; + } } requestMonitor.done(); } + /** + * Builds a delta in response to automatic refresh event generated after + * every suspend event. + *

+ * As opposed to the StackFrameVMNode handling of the refresh event, the + * container handles only the refresh events for container suspended events, + * and it refreshes the entire container. + *

+ * The default behavior is to check if the thread is still stepping or + * suspended and refresh the stack trace. + */ + protected void buildDeltaForFullStackRefreshEvent(final IContainerDMContext containerCtx, + final IExecutionDMContext[] triggeringCtxs, final VMDelta parentDelta, final int nodeOffset, + final RequestMonitor rm) + { + try { + getSession().getExecutor().execute(new DsfRunnable() { + @Override + public void run() { + IRunControl runControlService = getServicesTracker().getService(IRunControl.class); + if (runControlService == null) { + // Required services have not initialized yet. Ignore the event. + rm.done(); + return; + } + + // Refresh the whole list of stack frames unless the target is already stepping the next command. In + // which case, the refresh will occur when the stepping sequence slows down or stops. Trying to + // refresh the whole stack trace with every step would slow down stepping too much. + boolean isStepping = false; + for (IExecutionDMContext triggeringCtx : triggeringCtxs) { + if (runControlService.isStepping(triggeringCtx)) { + isStepping = true; + break; + } + } + if (!isStepping) { + parentDelta.addNode(createVMContext(containerCtx), IModelDelta.CONTENT); + } + + rm.done(); + } + }); + } catch (RejectedExecutionException e) { + // Session shut down, no delta to build. + rm.done(); + } + } + + } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractLaunchVMProvider.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractLaunchVMProvider.java index 62fc69003a9..8efe7799e53 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractLaunchVMProvider.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractLaunchVMProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems and others. + * Copyright (c) 2006, 2013 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -156,7 +156,8 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider } } } else if (event instanceof IRunControl.ISuspendedDMEvent) { - final IExecutionDMContext exeContext= ((IRunControl.ISuspendedDMEvent) event).getDMContext(); + final IRunControl.ISuspendedDMEvent suspendEvent = (IRunControl.ISuspendedDMEvent)event; + final IExecutionDMContext exeContext= suspendEvent.getDMContext(); ScheduledFuture refreshStackFramesFuture = getRefreshFuture(exeContext); // trigger delayed full stack frame update if (refreshStackFramesFuture != null) { @@ -177,7 +178,7 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider ScheduledFuture future= fRefreshStackFramesFutures.get(exeContext); if (future != null && !isDisposed()) { fRefreshStackFramesFutures.remove(exeContext); - handleEvent(new FullStackRefreshEvent(exeContext), null); + handleEvent(new FullStackRefreshEvent(exeContext, suspendEvent), null); } }}); } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/FullStackRefreshEvent.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/FullStackRefreshEvent.java index e9ba9985fb4..04538edcdbb 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/FullStackRefreshEvent.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/FullStackRefreshEvent.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2009 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2014 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,6 +11,8 @@ package org.eclipse.cdt.dsf.debug.ui.viewmodel.launch; import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.datamodel.IDMEvent; import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; /** @@ -21,8 +23,18 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; */ public class FullStackRefreshEvent extends AbstractDMEvent { + private final IDMEvent fTriggeringEvent; + public FullStackRefreshEvent(IExecutionDMContext execCtx) { + this(execCtx, null); + } + + public FullStackRefreshEvent(IExecutionDMContext execCtx, IDMEvent triggeringEvent) { super(execCtx); + fTriggeringEvent = triggeringEvent; } + public IDMEvent getTriggeringEvent() { + return fTriggeringEvent; + } } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java index bbe23094c6c..dd1a4c9b66f 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/StackFramesVMNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems and others. + * Copyright (c) 2006, 2014 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -606,7 +606,9 @@ public class StackFramesVMNode extends AbstractDMVMNode // label has changed. if (e instanceof ISuspendedDMEvent) { return IModelDelta.CONTENT | IModelDelta.EXPAND | IModelDelta.SELECT; - } else if (e instanceof FullStackRefreshEvent) { + } else if (e instanceof FullStackRefreshEvent && + !(((FullStackRefreshEvent)e).getTriggeringEvent() instanceof IContainerSuspendedDMEvent) ) + { return IModelDelta.CONTENT; } else if (e instanceof SteppingTimedOutEvent) { return IModelDelta.CONTENT; @@ -657,8 +659,15 @@ public class StackFramesVMNode extends AbstractDMVMNode rm.done(); } } else if (e instanceof FullStackRefreshEvent) { - IExecutionDMContext execDmc = ((FullStackRefreshEvent)e).getDMContext(); - buildDeltaForFullStackRefreshEvent(execDmc, execDmc, parent, nodeOffset, rm); + FullStackRefreshEvent refreshEvent = (FullStackRefreshEvent)e; + if ( !(refreshEvent.getTriggeringEvent() instanceof IContainerSuspendedDMEvent)) { + // Don't refresh each stack frame when we get an event for the entire container + // Bug 386175 + IExecutionDMContext execDmc = ((FullStackRefreshEvent)e).getDMContext(); + buildDeltaForFullStackRefreshEvent(execDmc, execDmc, parent, nodeOffset, rm); + } else { + rm.done(); + } } else if (e instanceof ISuspendedDMEvent) { resetStackFrameLimit( ((ISuspendedDMEvent)e).getDMContext() ); IExecutionDMContext execDmc = ((ISuspendedDMEvent)e).getDMContext();