From 5c5e9082f484f70102065fb523b13f3c72c2d216 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 23 May 2008 20:37:58 +0000 Subject: [PATCH] [233716] - [debug view][run control] Step buttons are still available when stepping over a sleep() call --- .../launch/AbstractContainerVMNode.java | 30 ++++++-- .../launch/AbstractThreadVMNode.java | 50 +++++++++---- .../viewmodel/launch/StackFramesVMNode.java | 71 +++++++++++++++---- .../update/AbstractCachingVMProvider.java | 12 ++-- 4 files changed, 124 insertions(+), 39 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractContainerVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractContainerVMNode.java index 302197fdb7f..5041ea27712 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractContainerVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractContainerVMNode.java @@ -18,9 +18,12 @@ import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerResumedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.IStartedDMEvent; +import org.eclipse.dd.dsf.debug.service.StepQueueManager.ISteppingTimedOutEvent; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; @@ -62,10 +65,16 @@ public abstract class AbstractContainerVMNode extends AbstractDMVMNode implement protected abstract void updateLabelInSessionThread(ILabelUpdate[] updates); public int getDeltaFlags(Object e) { - if(e instanceof IRunControl.IContainerResumedDMEvent || - e instanceof IRunControl.IContainerSuspendedDMEvent) + if (e instanceof IContainerResumedDMEvent && + ((IContainerResumedDMEvent)e).getReason() != IRunControl.StateChangeReason.STEP) + { + return IModelDelta.CONTENT; + } else if (e instanceof IContainerSuspendedDMEvent) { + return IModelDelta.CONTENT; + } else if (e instanceof ISteppingTimedOutEvent && + ((ISteppingTimedOutEvent)e).getDMContext() instanceof IContainerDMContext) { - return IModelDelta.CONTENT; + return IModelDelta.CONTENT; } else if (e instanceof IExitedDMEvent) { return IModelDelta.CONTENT; } else if (e instanceof IStartedDMEvent) { @@ -79,11 +88,20 @@ public abstract class AbstractContainerVMNode extends AbstractDMVMNode implement } public void buildDelta(Object e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { - if(e instanceof IRunControl.IContainerResumedDMEvent || - e instanceof IRunControl.IContainerSuspendedDMEvent) + if(e instanceof IContainerResumedDMEvent && + ((IContainerResumedDMEvent)e).getReason() != IRunControl.StateChangeReason.STEP) { parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); - } else if (e instanceof IExitedDMEvent) { + } else if (e instanceof IContainerSuspendedDMEvent) { + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); + } else if (e instanceof ISteppingTimedOutEvent && + ((ISteppingTimedOutEvent)e).getDMContext() instanceof IContainerDMContext) + { + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); + // Workaround for bug 233730: we need to add a separate delta node for the state flag in + // order to trigger an update of the run control actions. + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.STATE); + } else if (e instanceof IExitedDMEvent) { IExecutionDMContext exeContext= ((IExitedDMEvent) e).getDMContext(); if (exeContext instanceof IContainerDMContext) { parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractThreadVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractThreadVMNode.java index fc3fb1978aa..5cc2bb90f49 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractThreadVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractThreadVMNode.java @@ -209,31 +209,51 @@ public abstract class AbstractThreadVMNode extends AbstractDMVMNode public int getDeltaFlags(Object e) { - if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) { + if (e instanceof IContainerResumedDMEvent || e instanceof IContainerSuspendedDMEvent) { + // No need to react to container events, because the container + // nodes will deal with them. We need this if statement however, + // because the these events extend IResumedDMEvent and + // ISuspendedDMEvent and would trigger the if statement below. + return IModelDelta.NO_CHANGE; + } else if (e instanceof IResumedDMEvent && + ((IResumedDMEvent)e).getReason() != IRunControl.StateChangeReason.STEP) + { + return IModelDelta.CONTENT; + } else if (e instanceof ISuspendedDMEvent) { return IModelDelta.CONTENT; - } - if (e instanceof ModelProxyInstalledEvent) { + } else if (e instanceof ISteppingTimedOutEvent && + !(((ISteppingTimedOutEvent)e).getDMContext() instanceof IContainerDMContext) ) + { + return IModelDelta.CONTENT; + } else if (e instanceof ModelProxyInstalledEvent) { return IModelDelta.SELECT | IModelDelta.EXPAND; } return IModelDelta.NO_CHANGE; } public void buildDelta(Object e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { - if(e instanceof IContainerResumedDMEvent) { - IExecutionDMContext[] triggeringContexts = ((IContainerResumedDMEvent)e).getTriggeringContexts(); - if (triggeringContexts.length != 0) { - parentDelta.addNode(createVMContext(triggeringContexts[0]), IModelDelta.CONTENT); - } + if(e instanceof IContainerResumedDMEvent || e instanceof IContainerSuspendedDMEvent) { + // No need to react to container events, because the container + // nodes will deal with them. We need this if statement however, + // because the these events extend IResumedDMEvent and + // ISuspendedDMEvent and would trigger the if statement below. rm.done(); - } else if (e instanceof IContainerSuspendedDMEvent) { - IExecutionDMContext[] triggeringContexts = ((IContainerSuspendedDMEvent)e).getTriggeringContexts(); - if (triggeringContexts.length != 0) { - parentDelta.addNode(createVMContext(triggeringContexts[0]), IModelDelta.CONTENT); - } - rm.done(); - } else if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) { + } else if(e instanceof IResumedDMEvent && + ((IResumedDMEvent)e).getReason() != IRunControl.StateChangeReason.STEP) + { parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); rm.done(); + } else if (e instanceof ISuspendedDMEvent) { + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); + rm.done(); + } else if (e instanceof ISteppingTimedOutEvent && + !(((ISteppingTimedOutEvent)e).getDMContext() instanceof IContainerDMContext) ) + { + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.CONTENT); + // Workaround for bug 233730: we need to add a separate delta node for the state flag in + // order to trigger an update of the run control actions. + parentDelta.addNode(createVMContext(((IDMEvent)e).getDMContext()), IModelDelta.STATE); + rm.done(); } else if (e instanceof ModelProxyInstalledEvent) { getThreadVMCForModelProxyInstallEvent( parentDelta, diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java index 160be6d34df..6ebf9a4b4fb 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java @@ -38,6 +38,7 @@ import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; @@ -77,6 +78,30 @@ public class StackFramesVMNode extends AbstractDMVMNode update.done(); } + @Override + protected void updateElementCountInSessionThread(final IChildrenCountUpdate update) { + IStack stackService = getServicesTracker().getService(IStack.class); + final IExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class); + if (stackService == null || execDmc == null) { + handleFailedUpdate(update); + return; + } + + stackService.getStackDepth( + execDmc, 0, + new ViewerDataRequestMonitor(getSession().getExecutor(), update) { + @Override + public void handleCompleted() { + if (!isSuccess()) { + handleFailedUpdate(update); + return; + } + update.setChildCount(getData()); + update.done(); + } + }); + } + /* * (non-Javadoc) * @see org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode#updateElementsInSessionThread(org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate) @@ -90,19 +115,37 @@ public class StackFramesVMNode extends AbstractDMVMNode return; } - stackService.getFrames( - execDmc, - new ViewerDataRequestMonitor(getSession().getExecutor(), update) { - @Override - public void handleCompleted() { - if (!isSuccess()) { - handleFailedUpdate(update); - return; + if (update.getOffset() == 0 && update.getLength() == 1) { + stackService.getTopFrame( + execDmc, + new ViewerDataRequestMonitor(getSession().getExecutor(), update) { + @Override + public void handleCompleted() { + if (!isSuccess()) { + handleFailedUpdate(update); + return; + } + update.setChild(createVMContext(getData()), 0); + update.done(); } - fillUpdateWithVMCs(update, getData()); - update.done(); - } - }); + }); + + // Requesting top stack frame only + } else { + stackService.getFrames( + execDmc, + new ViewerDataRequestMonitor(getSession().getExecutor(), update) { + @Override + public void handleCompleted() { + if (!isSuccess()) { + handleFailedUpdate(update); + return; + } + fillUpdateWithVMCs(update, getData()); + update.done(); + } + }); + } } /* @@ -249,7 +292,7 @@ public class StackFramesVMNode extends AbstractDMVMNode getVMProvider().updateNode( this, new VMChildrenUpdate( - parentDelta, getVMProvider().getPresentationContext(), -1, -1, + parentDelta, getVMProvider().getPresentationContext(), 0, 1, new DataRequestMonitor>(getExecutor(), rm) { @Override public void handleCompleted() { @@ -391,7 +434,7 @@ public class StackFramesVMNode extends AbstractDMVMNode private void buildDeltaForSteppingTimedOutEvent(final StepQueueManager.ISteppingTimedOutEvent e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) { // Repaint the stack frame images to have the running symbol. - parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + //parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); rm.done(); } diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java index c4c90acc58b..3b864b84f2e 100644 --- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java @@ -11,6 +11,7 @@ package org.eclipse.dd.dsf.ui.viewmodel.update; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; @@ -238,7 +239,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa * Also, the ordering is used to optimize the flushing of the cache data (see * {@link FlushMarkerKey} for more details). */ - private final Map fCacheData = new HashMap(200, 0.75f); + private final Map fCacheData = Collections.synchronizedMap(new HashMap(200, 0.75f)); /** * Pointer to the first cache entry in the double-linked list of cache entries. @@ -758,9 +759,12 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa @Deprecated public IDMData getArchivedModelData(IVMNode node, IViewerUpdate update, IDMContext dmc) { ElementDataKey key = makeEntryKey(node, update); - final ElementDataEntry entry = getElementDataEntry(key); - if ( entry.fArchiveData != null) { - return entry.fArchiveData.get(dmc); + final Entry entry = fCacheData.get(key); + if ( entry instanceof ElementDataEntry) { + Map archiveData = ((ElementDataEntry)entry).fArchiveData; + if (archiveData != null) { + return archiveData.get(dmc); + } } return null; }