1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-25 18:05:33 +02:00

214386: [run control][debug view][source lookup] When stepping fast (holding down F5 key) the IP in editor does not keep up.

This commit is contained in:
Anton Leherbauer 2008-07-16 11:02:58 +00:00
parent e5930da951
commit 337235a75e
38 changed files with 1494 additions and 229 deletions

View file

@ -0,0 +1,65 @@
/*******************************************************************************
* Copyright (c) 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel;
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController.ISteppingControlParticipant;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
/**
* Base class for VM adapters used for implementing a debugger integration.
*
* @since 1.1
*/
@SuppressWarnings("restriction")
public class AbstractDebugVMAdapter extends AbstractDMVMAdapter
implements ISteppingControlParticipant
{
public AbstractDebugVMAdapter(DsfSession session, SteppingController controller) {
super(session);
fController = controller;
fController.addSteppingControlParticipant(this);
}
private SteppingController fController;
@Override
protected IVMProvider createViewModelProvider(IPresentationContext context) {
return null;
}
@Override
public void doneHandleEvent(Object event) {
if (event instanceof IRunControl.ISuspendedDMEvent) {
final ISuspendedDMEvent suspendedEvent= (IRunControl.ISuspendedDMEvent) event;
fController.getExecutor().execute(new DsfRunnable() {
public void run() {
fController.doneStepping(suspendedEvent.getDMContext(), AbstractDebugVMAdapter.this);
};
});
}
}
@Override
public void dispose() {
if (fController != null) {
fController.removeSteppingControlParticipant(this);
fController = null;
}
super.dispose();
}
}

View file

@ -0,0 +1,593 @@
/*******************************************************************************
* Copyright (c) 2006, 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.IStepQueueManager;
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
import org.eclipse.dd.dsf.debug.service.IRunControl.StepType;
import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants;
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
import org.eclipse.dd.dsf.service.DsfServicesTracker;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
/**
* This class builds on top of standard run control service to provide
* functionality for step queuing and delaying. Step queuing essentially allows
* user to press and hold the step key and achieve maximum stepping speed. If
* this class is used, other service implementations, such as stack and
* expressions, can use it to avoid requesting data from debugger back end if
* another step is about to be executed.
*
* @since 1.1
*/
public final class SteppingController implements IStepQueueManager
{
/**
* Amount of time in milliseconds, that it takes the SteppingTimedOutEvent
* event to be issued after a step is started.
* @see SteppingTimedOutEvent
*/
public final static int STEPPING_TIMEOUT = 500;
/**
* The depth of the step queue. In other words, the maximum number of steps
* that are queued before the step queue manager is throwing them away.
*/
public final static int STEP_QUEUE_DEPTH = 1;
/**
* The maximum delay (in milliseconds) between steps when synchronized
* stepping is enabled. This also serves as a safeguard in the case stepping
* control participants fail to indicate completion of event processing.
*/
public final static int MAX_STEP_DELAY= 1000;
/**
* Indicates that the given context has been stepping for some time,
* and the UI (views and actions) may need to be updated accordingly.
*/
public static final class SteppingTimedOutEvent extends AbstractDMEvent<IExecutionDMContext> {
private SteppingTimedOutEvent(IExecutionDMContext execCtx) {
super(execCtx);
}
}
/**
* Interface for clients interested in stepping control. When a stepping
* control participant is registered with the stepping controller, it is
* expected to call
* {@link SteppingController#doneStepping(IExecutionDMContext, ISteppingControlParticipant)
* doneStepping} as soon as a "step", i.e. a suspended event has been
* processed. If synchronized stepping is enabled, further stepping is
* blocked until all stepping control participants have indicated completion
* of event processing or the maximum timeout
* {@link SteppingController#MAX_STEP_DELAY} has been reached.
*
* @see SteppingController#addSteppingControlParticipant(ISteppingControlParticipant)
* @see SteppingController#removeSteppingControlParticipant(ISteppingControlParticipant)
*/
public interface ISteppingControlParticipant {
}
private static class StepRequest {
StepType fStepType;
StepRequest(StepType type) {
fStepType = type;
}
}
private final DsfSession fSession;
private final DsfServicesTracker fServicesTracker;
private IRunControl fRunControl;
private int fQueueDepth = STEP_QUEUE_DEPTH;
private final Map<IExecutionDMContext,List<StepRequest>> fStepQueues = new HashMap<IExecutionDMContext,List<StepRequest>>();
private final Map<IExecutionDMContext,Boolean> fTimedOutFlags = new HashMap<IExecutionDMContext,Boolean>();
private final Map<IExecutionDMContext,ScheduledFuture<?>> fTimedOutFutures = new HashMap<IExecutionDMContext,ScheduledFuture<?>>();
/**
* Records the time of the last step for an execution context.
*/
private final Map<IExecutionDMContext, Long> fLastStepTimes= new HashMap<IExecutionDMContext, Long>();
/**
* Minimum step interval in milliseconds.
*/
private int fMinStepInterval= 0;
/**
* Whether synchronized stepping is enabled.
*/
private boolean fSynchronizedStepping;
/**
* Map of execution contexts for which a step is in progress.
*/
private final Map<IExecutionDMContext, List<ISteppingControlParticipant>> fStepInProgress = new HashMap<IExecutionDMContext, List<ISteppingControlParticipant>>();
/**
* List of registered stepping control participants.
*/
private final List<ISteppingControlParticipant> fParticipants = Collections.synchronizedList(new ArrayList<ISteppingControlParticipant>());
/**
* Property change listener. It updates the stepping control settings.
*/
private IPropertyChangeListener fPreferencesListener;
public SteppingController(DsfSession session) {
fSession = session;
fServicesTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
final IPreferenceStore store= DsfDebugUIPlugin.getDefault().getPreferenceStore();
fPreferencesListener = new IPropertyChangeListener() {
public void propertyChange(final PropertyChangeEvent event) {
handlePropertyChanged(store, event);
}};
store.addPropertyChangeListener(fPreferencesListener);
enableSynchronizedStepping(store.getBoolean(IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE));
setMinimumStepInterval(store.getInt(IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL));
}
public void dispose() {
if (fRunControl != null) {
getSession().removeServiceEventListener(this);
}
IPreferenceStore store= DsfDebugUIPlugin.getDefault().getPreferenceStore();
store.removePropertyChangeListener(fPreferencesListener);
fServicesTracker.dispose();
}
/**
* Enables or disables synchronized stepping mode.
* In synchronized mode, after a step command is issued,
* subsequent steps are blocked for the execution context
* until {@link #doneStepping()} is called to indicate completion
* of the processing for the last step.
*
* @param enable
*/
public void enableSynchronizedStepping(boolean enable) {
fSynchronizedStepping = enable;
}
/**
* Configure the minimum time (in milliseconds) to wait between steps.
*
* @param interval
*/
public void setMinimumStepInterval(int interval) {
fMinStepInterval = interval;
}
/**
* Register given stepping control participant.
* <p>
* Participants are obliged to call
* {@link #doneStepping(IExecutionDMContext, ISteppingControlParticipant)}
* when they have received and completed processing an
* {@link ISuspendedDMEvent}. If synchronized stepping is enabled, further
* stepping is disabled until all participants have indicated completion of
* processing the event.
* </p>
*
* @param participant
*/
public void addSteppingControlParticipant(ISteppingControlParticipant participant) {
fParticipants.add(participant);
}
/**
* Unregister given stepping control participant.
*
* @param participant
*/
public void removeSteppingControlParticipant(final ISteppingControlParticipant participant) {
fParticipants.remove(participant);
// remove participant from steps in progress
if (fSynchronizedStepping) {
getExecutor().execute(new DsfRunnable() {
public void run() {
for (IExecutionDMContext disabledCtx : fStepInProgress.keySet()) {
List<ISteppingControlParticipant> participants= fStepInProgress.get(disabledCtx);
if (participants != null) {
participants.remove(participant);
if (participants.isEmpty()) {
fStepInProgress.remove(disabledCtx);
}
}
}
}});
}
}
/**
* Indicate that participant has completed processing of the last step.
*
* @param execCtx
*/
public void doneStepping(final IExecutionDMContext execCtx, final ISteppingControlParticipant participant) {
List<ISteppingControlParticipant> participants = fStepInProgress.get(execCtx);
if (participants != null) {
participants.remove(participant);
if (participants.isEmpty()) {
doneStepping(execCtx);
}
} else {
for (IExecutionDMContext disabledCtx : fStepInProgress.keySet()) {
if (DMContexts.isAncestorOf(disabledCtx, execCtx)) {
participants = fStepInProgress.get(disabledCtx);
if (participants != null) {
participants.remove(participant);
if (participants.isEmpty()) {
doneStepping(disabledCtx);
}
}
}
}
}
}
public DsfSession getSession() {
return fSession;
}
/**
* All access to this class should happen through this executor.
* @return the executor this class is confined to
*/
public DsfExecutor getExecutor() {
return getSession().getExecutor();
}
private DsfServicesTracker getServicesTracker() {
return fServicesTracker;
}
private IRunControl getRunControl() {
if (fRunControl == null) {
fRunControl = getServicesTracker().getService(IRunControl.class);
getSession().addServiceEventListener(this, null);
}
return fRunControl;
}
/**
* Checks whether a step command can be queued up for given context.
*/
public void canEnqueueStep(IExecutionDMContext execCtx, StepType stepType, DataRequestMonitor<Boolean> rm) {
if (doCanEnqueueStep(execCtx, stepType)) {
rm.setData(true);
rm.done();
} else {
getRunControl().canStep(execCtx, stepType, rm);
}
}
private boolean doCanEnqueueStep(IExecutionDMContext execCtx, StepType stepType) {
return getRunControl().isStepping(execCtx) && !isSteppingTimedOut(execCtx);
}
/**
* Check whether the next step on the given execution context should be delayed
* based on the configured step delay.
*
* @param execCtx
* @return <code>true</code> if the step should be delayed
*/
private boolean shouldDelayStep(IExecutionDMContext execCtx) {
return getStepDelay(execCtx) > 0;
}
/**
* Compute the delay in milliseconds before the next step for the given context may be executed.
*
* @param execCtx
* @return the number of milliseconds before the next possible step
*/
private int getStepDelay(IExecutionDMContext execCtx) {
if (fMinStepInterval > 0) {
for (IExecutionDMContext lastStepCtx : fLastStepTimes.keySet()) {
if (execCtx.equals(lastStepCtx) || DMContexts.isAncestorOf(execCtx, lastStepCtx)) {
long now = System.currentTimeMillis();
int delay= (int) (fLastStepTimes.get(lastStepCtx) + fMinStepInterval - now);
return Math.max(delay, 0);
}
}
}
return 0;
}
private void updateLastStepTime(IExecutionDMContext execCtx) {
long now = System.currentTimeMillis();
fLastStepTimes.put(execCtx, now);
for (IExecutionDMContext lastStepCtx : fLastStepTimes.keySet()) {
if (!execCtx.equals(lastStepCtx) && DMContexts.isAncestorOf(execCtx, lastStepCtx)) {
fLastStepTimes.put(lastStepCtx, now);
}
}
}
private long getLastStepTime(IExecutionDMContext execCtx) {
if (fLastStepTimes.containsKey(execCtx)) {
return fLastStepTimes.get(execCtx);
}
for (IExecutionDMContext lastStepCtx : fLastStepTimes.keySet()) {
if (DMContexts.isAncestorOf(execCtx, lastStepCtx)) {
return fLastStepTimes.get(lastStepCtx);
}
}
return 0;
}
/**
* Returns the number of step commands that are queued for given execution
* context.
*/
public int getPendingStepCount(IExecutionDMContext execCtx) {
List<StepRequest> stepQueue = fStepQueues.get(execCtx);
if (stepQueue == null) return 0;
return stepQueue.size();
}
/**
* Adds a step command to the execution queue for given context.
* @param execCtx Execution context that should perform the step.
* @param stepType Type of step to execute.
*/
public void enqueueStep(final IExecutionDMContext execCtx, final StepType stepType) {
if (shouldDelayStep(execCtx)) {
if (doCanEnqueueStep(execCtx, stepType)) {
doEnqueueStep(execCtx, stepType);
if (!getRunControl().isStepping(execCtx)) {
processStepQueue(execCtx);
}
}
} else {
getRunControl().canStep(
execCtx, stepType, new DataRequestMonitor<Boolean>(getExecutor(), null) {
@Override
protected void handleCompleted() {
if (isSuccess() && getData()) {
if (isSteppingDisabled(execCtx)) {
doEnqueueStep(execCtx, stepType);
} else {
doStep(execCtx, stepType);
}
} else if (doCanEnqueueStep(execCtx, stepType)) {
doEnqueueStep(execCtx, stepType);
}
}
});
}
}
private void doStep(final IExecutionDMContext execCtx, final StepType stepType) {
if (fSynchronizedStepping) {
disableStepping(execCtx);
}
updateLastStepTime(execCtx);
getRunControl().step(execCtx, stepType, new RequestMonitor(getExecutor(), null));
}
/**
* Enqueue the given step for later execution.
*
* @param execCtx
* @param stepType
*/
private void doEnqueueStep(final IExecutionDMContext execCtx, final StepType stepType) {
List<StepRequest> stepQueue = fStepQueues.get(execCtx);
if (stepQueue == null) {
stepQueue = new LinkedList<StepRequest>();
fStepQueues.put(execCtx, stepQueue);
}
if (stepQueue.size() < fQueueDepth) {
stepQueue.add(new StepRequest(stepType));
}
}
/**
* Returns whether the step instruction for the given context has timed out.
*/
public boolean isSteppingTimedOut(IExecutionDMContext execCtx) {
for (IExecutionDMContext timedOutCtx : fTimedOutFlags.keySet()) {
if (execCtx.equals(timedOutCtx) || DMContexts.isAncestorOf(execCtx, timedOutCtx)) {
return fTimedOutFlags.get(timedOutCtx);
}
}
return false;
}
/**
* Process next step on queue if any.
* @param execCtx
*/
private void processStepQueue(final IExecutionDMContext execCtx) {
if (isSteppingDisabled(execCtx)) {
return;
}
if (fStepQueues.containsKey(execCtx)) {
final int stepDelay = getStepDelay(execCtx);
if (stepDelay > 0) {
getExecutor().schedule(new DsfRunnable() {
public void run() {
processStepQueue(execCtx);
}
}, stepDelay, TimeUnit.MILLISECONDS);
return;
}
List<StepRequest> queue = fStepQueues.get(execCtx);
final StepRequest request = queue.remove(queue.size() - 1);
if (queue.isEmpty()) fStepQueues.remove(execCtx);
getRunControl().canStep(
execCtx, request.fStepType,
new DataRequestMonitor<Boolean>(getExecutor(), null) {
@Override
protected void handleCompleted() {
if (isSuccess() && getData()) {
doStep(execCtx, request.fStepType);
} else {
// For whatever reason we can't step anymore, so clear out
// the step queue.
fStepQueues.remove(execCtx);
}
}
});
}
}
/**
* Disable stepping for the given execution context.
*
* @param execCtx
*/
private void disableStepping(IExecutionDMContext execCtx) {
fStepInProgress.put(execCtx, new ArrayList<ISteppingControlParticipant>(fParticipants));
}
/**
* Indicate that processing of the last step has completed and
* the next step can be issued.
*
* @param execCtx
*/
private void doneStepping(final IExecutionDMContext execCtx) {
if (fSynchronizedStepping) {
enableStepping(execCtx);
processStepQueue(execCtx);
}
}
/**
* Enable stepping for the given execution context.
*
* @param execCtx
*/
private void enableStepping(final IExecutionDMContext execCtx) {
fStepInProgress.remove(execCtx);
for (IExecutionDMContext disabledCtx : fStepInProgress.keySet()) {
if (DMContexts.isAncestorOf(disabledCtx, execCtx)) {
fStepInProgress.remove(disabledCtx);
}
}
}
private boolean isSteppingDisabled(IExecutionDMContext execCtx) {
if (fSynchronizedStepping) {
boolean disabled= fStepInProgress.containsKey(execCtx);
if (!disabled) {
for (IExecutionDMContext disabledCtx : fStepInProgress.keySet()) {
if (DMContexts.isAncestorOf(execCtx, disabledCtx)) {
disabled = true;
break;
}
}
}
if (disabled) {
long now = System.currentTimeMillis();
long lastStepTime = getLastStepTime(execCtx);
if (now - lastStepTime > MAX_STEP_DELAY) {
enableStepping(execCtx);
disabled = false;
}
}
return disabled;
}
return false;
}
protected void handlePropertyChanged(final IPreferenceStore store, final PropertyChangeEvent event) {
String property = event.getProperty();
if (IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE.equals(property)) {
enableSynchronizedStepping(store.getBoolean(property));
} else if (IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL.equals(property)) {
setMinimumStepInterval(store.getInt(property));
}
}
///////////////////////////////////////////////////////////////////////////
@DsfServiceEventHandler
public void eventDispatched(final ISuspendedDMEvent e) {
// Take care of the stepping time out
fTimedOutFlags.remove(e.getDMContext());
ScheduledFuture<?> future = fTimedOutFutures.remove(e.getDMContext());
if (future != null) future.cancel(false);
// Check if there's a step pending, if so execute it
processStepQueue(e.getDMContext());
}
@DsfServiceEventHandler
public void eventDispatched(final IResumedDMEvent e) {
if (e.getReason().equals(StateChangeReason.STEP)) {
fTimedOutFlags.put(e.getDMContext(), Boolean.FALSE);
// We shouldn't have a stepping timeout running unless we get two
// stepping events in a row without a suspended, which would be a
// protocol error.
assert !fTimedOutFutures.containsKey(e.getDMContext());
fTimedOutFutures.put(
e.getDMContext(),
getExecutor().schedule(
new DsfRunnable() { public void run() {
fTimedOutFutures.remove(e.getDMContext());
if (getSession().isActive()) {
// Issue the stepping time-out event.
getSession().dispatchEvent(
new SteppingTimedOutEvent(e.getDMContext()),
null);
}
}},
STEPPING_TIMEOUT, TimeUnit.MILLISECONDS)
);
}
}
@DsfServiceEventHandler
public void eventDispatched(SteppingTimedOutEvent e) {
fTimedOutFlags.put(e.getDMContext(), Boolean.TRUE);
enableStepping(e.getDMContext());
}
}

View file

@ -18,6 +18,7 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController.SteppingTimedOutEvent;
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;
@ -37,6 +38,8 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
/**
* Abstract implementation of a container view model node.
* Clients need to implement {@link #updateLabelInSessionThread(ILabelUpdate[])}.
*
* @since 1.1
*/
@SuppressWarnings("restriction")
public abstract class AbstractContainerVMNode extends AbstractDMVMNode implements IElementLabelProvider {
@ -87,6 +90,11 @@ public abstract class AbstractContainerVMNode extends AbstractDMVMNode implement
if (dmc instanceof IContainerDMContext) {
return IModelDelta.CONTENT;
}
} else if (e instanceof SteppingTimedOutEvent) {
if (dmc instanceof IContainerDMContext)
{
return IModelDelta.CONTENT;
}
} else if (e instanceof ISteppingTimedOutEvent) {
if (dmc instanceof IContainerDMContext)
{
@ -129,6 +137,15 @@ public abstract class AbstractContainerVMNode extends AbstractDMVMNode implement
if (dmc instanceof IContainerDMContext) {
parentDelta.addNode(createVMContext(dmc), IModelDelta.CONTENT);
}
} else if (e instanceof SteppingTimedOutEvent) {
// Stepping time-out indicates that a step operation is taking
// a long time, and the view needs to be refreshed to show
// the user that the program is running.
// If the step was issued for the whole container refresh
// the whole container.
if (dmc instanceof IContainerDMContext) {
parentDelta.addNode(createVMContext(dmc), IModelDelta.CONTENT);
}
} else if (e instanceof ISteppingTimedOutEvent) {
// Stepping time-out indicates that a step operation is taking
// a long time, and the view needs to be refreshed to show

View file

@ -54,7 +54,7 @@ import org.eclipse.jface.viewers.IStructuredSelection;
/**
*
* @since 1.1
*/
@SuppressWarnings("restriction")
public class AbstractLaunchVMProvider extends AbstractDMVMProvider
@ -81,20 +81,7 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider
fPreferencesListener = new IPropertyChangeListener() {
public void propertyChange(final PropertyChangeEvent event) {
String property = event.getProperty();
if (IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE.equals(property)
|| IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT.equals(property)) {
if (store.getBoolean(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE)) {
getPresentationContext().setProperty(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, store.getInt(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT));
} else {
getPresentationContext().setProperty(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, null);
}
getExecutor().execute(new DsfRunnable() {
public void run() {
handleEvent(event);
}
});
}
handlePropertyChanged(store, event);
}};
store.addPropertyChangeListener(fPreferencesListener);
}
@ -128,30 +115,33 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider
}
@Override
public void handleEvent(Object event) {
public void handleEvent(Object event, final RequestMonitor rm) {
if (event instanceof DoubleClickEvent && !isDisposed()) {
final ISelection selection= ((DoubleClickEvent) event).getSelection();
if (selection instanceof IStructuredSelection) {
Object element= ((IStructuredSelection) selection).getFirstElement();
if (element instanceof IncompleteStackVMContext) {
IncompleteStackVMContext incStackVmc = ((IncompleteStackVMContext) element);
IVMNode node = ((IncompleteStackVMContext) element).getVMNode();
if (incStackVmc.getVMNode() instanceof StackFramesVMNode) {
IVMNode node = incStackVmc.getVMNode();
if (node instanceof StackFramesVMNode && node.getVMProvider() == this) {
IExecutionDMContext exeCtx= incStackVmc.getExecutionDMContext();
((StackFramesVMNode) node).incrementStackFrameLimit(exeCtx);
// replace double click event with expand stack event
final ExpandStackEvent expandStackEvent = new ExpandStackEvent(exeCtx);
getExecutor().execute(new DsfRunnable() {
public void run() {
handleEvent(expandStackEvent);
handleEvent(expandStackEvent, null);
}
});
}
}
}
if (rm != null) {
rm.done();
}
return;
}
super.handleEvent(event);
super.handleEvent(event, rm);
}
@Override
@ -177,7 +167,7 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider
ScheduledFuture<?> future= fRefreshStackFramesFutures.get(exeContext);
if (future != null && !isDisposed()) {
fRefreshStackFramesFutures.remove(exeContext);
handleEvent(new FullStackRefreshEvent(exeContext));
handleEvent(new FullStackRefreshEvent(exeContext), null);
}
}});
}
@ -276,4 +266,21 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider
return false;
}
protected void handlePropertyChanged(final IPreferenceStore store, final PropertyChangeEvent event) {
String property = event.getProperty();
if (IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE.equals(property)
|| IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT.equals(property)) {
if (store.getBoolean(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE)) {
getPresentationContext().setProperty(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, store.getInt(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT));
} else {
getPresentationContext().setProperty(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, null);
}
getExecutor().execute(new DsfRunnable() {
public void run() {
handleEvent(event);
}
});
}
}
}

View file

@ -23,6 +23,7 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController.SteppingTimedOutEvent;
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;
@ -50,6 +51,8 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
/**
* Abstract implementation of a thread view model node.
* Clients need to implement {@link #updateLabelInSessionThread(ILabelUpdate[])}.
*
* @since 1.1
*/
@SuppressWarnings("restriction")
public abstract class AbstractThreadVMNode extends AbstractDMVMNode
@ -112,6 +115,15 @@ public abstract class AbstractThreadVMNode extends AbstractDMVMNode
rm.done();
return;
}
} else if (e instanceof SteppingTimedOutEvent &&
((SteppingTimedOutEvent)e).getDMContext() instanceof IContainerDMContext)
{
// The timed out event occured on a container and not on a thread. Do not
// return a context for this event, which will force the view model to generate
// a delta for all the threads.
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "", null)); //$NON-NLS-1$
rm.done();
return;
} else if (e instanceof ISteppingTimedOutEvent &&
((ISteppingTimedOutEvent)e).getDMContext() instanceof IContainerDMContext)
{
@ -232,6 +244,8 @@ public abstract class AbstractThreadVMNode extends AbstractDMVMNode
return IModelDelta.NO_CHANGE;
} else if (e instanceof FullStackRefreshEvent) {
return IModelDelta.CONTENT;
} else if (e instanceof SteppingTimedOutEvent) {
return IModelDelta.CONTENT;
} else if (e instanceof ISteppingTimedOutEvent) {
return IModelDelta.CONTENT;
} else if (e instanceof ModelProxyInstalledEvent) {
@ -271,6 +285,12 @@ public abstract class AbstractThreadVMNode extends AbstractDMVMNode
// and a fixed delay. Refresh the whole thread upon this event.
parentDelta.addNode(createVMContext(dmc), IModelDelta.CONTENT);
rm.done();
} else if (e instanceof SteppingTimedOutEvent) {
// Stepping time-out indicates that a step operation is taking
// a long time, and the view needs to be refreshed to show
// the user that the program is running.
parentDelta.addNode(createVMContext(dmc), IModelDelta.CONTENT);
rm.done();
} else if (e instanceof ISteppingTimedOutEvent) {
// Stepping time-out indicates that a step operation is taking
// a long time, and the view needs to be refreshed to show

View file

@ -31,6 +31,8 @@ import org.eclipse.jface.viewers.TreePath;
* The underlying base update policy is considered for container contexts only.
* In other cases the cache data is always flushed.
* </p>
*
* @since 1.1
*/
public class DelayedStackRefreshUpdatePolicy extends UpdatePolicyDecorator {

View file

@ -15,6 +15,8 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
/**
* Event to increase the stack frame limit for an execution context.
*
* @since 1.1
*/
public class ExpandStackEvent extends AbstractDMEvent<IExecutionDMContext> {

View file

@ -16,6 +16,8 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
/**
* Indicates the end of a sequence of steps. Should be handled like a suspended
* event to trigger a full refresh of stack frames.
*
* @since 1.1
*/
public class FullStackRefreshEvent extends AbstractDMEvent<IExecutionDMContext> {

View file

@ -12,6 +12,9 @@ package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch;
import org.eclipse.osgi.util.NLS;
/**
* @since 1.1
*/
public class LaunchVMUpdateMessages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.LaunchVMUpdateMessages";//$NON-NLS-1$

View file

@ -22,10 +22,11 @@ import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController.SteppingTimedOutEvent;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.IStack;
import org.eclipse.dd.dsf.debug.service.IStack2;
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
@ -33,6 +34,7 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent;
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData;
import org.eclipse.dd.dsf.debug.service.StepQueueManager.ISteppingTimedOutEvent;
import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor;
@ -65,6 +67,8 @@ public class StackFramesVMNode extends AbstractDMVMNode
/**
* View model context representing the end of an incomplete stack.
*
* @since 1.1
*/
public class IncompleteStackVMContext extends AbstractVMContext {
private final int fLevel;
@ -320,13 +324,16 @@ public class StackFramesVMNode extends AbstractDMVMNode
if (idx != 0) return;
final IExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class);
if (execDmc == null) {
return;
}
IRunControl runControlService = getServicesTracker().getService(IRunControl.class);
StepQueueManager stepQueueMgrService = getServicesTracker().getService(StepQueueManager.class);
if (execDmc == null || runControlService == null || stepQueueMgrService == null) return;
SteppingController stepQueueMgr = (SteppingController) execDmc.getAdapter(SteppingController.class);
if (runControlService == null || stepQueueMgr == null) return;
String imageKey = null;
if (runControlService.isSuspended(execDmc) ||
(runControlService.isStepping(execDmc) && !stepQueueMgrService.isSteppingTimedOut(execDmc)))
(runControlService.isStepping(execDmc) && !stepQueueMgr.isSteppingTimedOut(execDmc)))
{
imageKey = IDebugUIConstants.IMG_OBJS_STACKFRAME;
} else {
@ -409,7 +416,9 @@ public class StackFramesVMNode extends AbstractDMVMNode
return IModelDelta.CONTENT | IModelDelta.EXPAND | IModelDelta.SELECT;
} else if (e instanceof FullStackRefreshEvent) {
return IModelDelta.CONTENT | IModelDelta.EXPAND;
} else if (e instanceof StepQueueManager.ISteppingTimedOutEvent) {
} else if (e instanceof SteppingTimedOutEvent) {
return IModelDelta.CONTENT;
} else if (e instanceof ISteppingTimedOutEvent) {
return IModelDelta.CONTENT;
} else if (e instanceof ModelProxyInstalledEvent) {
return IModelDelta.SELECT | IModelDelta.EXPAND;
@ -461,8 +470,10 @@ public class StackFramesVMNode extends AbstractDMVMNode
clearStackFrameLimit( ((ISuspendedDMEvent)e).getDMContext() );
IExecutionDMContext execDmc = ((ISuspendedDMEvent)e).getDMContext();
buildDeltaForSuspendedEvent(execDmc, execDmc, parent, nodeOffset, rm);
} else if (e instanceof StepQueueManager.ISteppingTimedOutEvent) {
buildDeltaForSteppingTimedOutEvent((StepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, rm);
} else if (e instanceof SteppingTimedOutEvent) {
buildDeltaForSteppingTimedOutEvent((SteppingTimedOutEvent)e, parent, nodeOffset, rm);
} else if (e instanceof ISteppingTimedOutEvent) {
buildDeltaForSteppingTimedOutEvent((ISteppingTimedOutEvent)e, parent, nodeOffset, rm);
} else if (e instanceof ModelProxyInstalledEvent) {
buildDeltaForModelProxyInstalledEvent(parent, nodeOffset, rm);
} else if (e instanceof ExpandStackEvent) {
@ -549,7 +560,13 @@ public class StackFramesVMNode extends AbstractDMVMNode
rm.done();
}
private void buildDeltaForSteppingTimedOutEvent(final StepQueueManager.ISteppingTimedOutEvent e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) {
private void buildDeltaForSteppingTimedOutEvent(final SteppingTimedOutEvent 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);
rm.done();
}
private void buildDeltaForSteppingTimedOutEvent(final 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);
rm.done();
@ -662,6 +679,8 @@ public class StackFramesVMNode extends AbstractDMVMNode
* Get the current active stack frame limit. If no limit is applicable {@link Integer.MAX_VALUE} is returned.
*
* @return the current stack frame limit
*
* @since 1.1
*/
public int getStackFrameLimit(IExecutionDMContext execCtx) {
if (fTemporaryLimits.containsKey(execCtx)) {
@ -691,6 +710,8 @@ public class StackFramesVMNode extends AbstractDMVMNode
/**
* Increment the stack frame limit by the default increment.
* This implementation doubles the current limit.
*
* @since 1.1
*/
public void incrementStackFrameLimit(IExecutionDMContext execCtx) {
final int stackFrameLimit= getStackFrameLimit(execCtx);

View file

@ -12,6 +12,7 @@ package org.eclipse.dd.dsf.debug.internal.ui.preferences;
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.IntegerFieldEditor;
@ -33,7 +34,7 @@ public class DsfDebugPreferencePage extends FieldEditorPreferencePage implements
* Mandatory default constructor (executable extension).
*/
public DsfDebugPreferencePage() {
super(GRID);
super(FLAT);
IPreferenceStore store= DsfDebugUIPlugin.getDefault().getPreferenceStore();
setPreferenceStore(store);
setDescription(MessagesForPreferences.DsfDebugPreferencePage_description);
@ -53,26 +54,54 @@ public class DsfDebugPreferencePage extends FieldEditorPreferencePage implements
@Override
protected void createFieldEditors() {
Group performanceGroup= new Group(getFieldEditorParent(), SWT.NONE);
final Composite parent= getFieldEditorParent();
final GridLayout layout= new GridLayout();
layout.marginWidth= 0;
parent.setLayout(layout);
Group performanceGroup= new Group(parent, SWT.NONE);
performanceGroup.setText(MessagesForPreferences.DsfDebugPreferencePage_performanceGroup_label);
performanceGroup.setLayout(new GridLayout());
GridData gd= new GridData(GridData.FILL_HORIZONTAL);
gd.verticalIndent= 5;
performanceGroup.setLayoutData(gd);
Composite innerParent= new Composite(performanceGroup, SWT.NONE);
innerParent.setLayout(new GridLayout());
innerParent.setLayoutData(gd);
GridLayout groupLayout= new GridLayout(3, false);
performanceGroup.setLayout(groupLayout);
performanceGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
// stack frame limit
IntegerFieldEditor limitEditor= new IntegerWithBooleanFieldEditor(
IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE,
IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT,
MessagesForPreferences.DsfDebugPreferencePage_limitStackFrames_label,
innerParent);
performanceGroup);
limitEditor.setValidRange(1, Integer.MAX_VALUE);
limitEditor.fillIntoGrid(innerParent, 3);
limitEditor.fillIntoGrid(performanceGroup, 3);
addField(limitEditor);
// sync stepping speed
BooleanFieldEditor syncSteppingEditor= new BooleanFieldEditor(
IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE,
MessagesForPreferences.DsfDebugPreferencePage_syncStepping_label,
performanceGroup);
syncSteppingEditor.fillIntoGrid(performanceGroup, 3);
addField(syncSteppingEditor);
// minimum step interval
IntegerFieldEditor minIntervalEditor= new IntegerFieldEditor(
IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL,
MessagesForPreferences.DsfDebugPreferencePage_minStepInterval_label,
performanceGroup);
minIntervalEditor.setValidRange(0, 10000);
minIntervalEditor.fillIntoGrid(performanceGroup, 3);
addField(minIntervalEditor);
// need to set layout again
performanceGroup.setLayout(groupLayout);
}
@Override
protected void adjustGridLayout() {
// do nothing
}
}

View file

@ -14,8 +14,10 @@ import org.eclipse.jface.preference.IntegerFieldEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
/**
* An integer field editor with an enablement check box.
@ -42,20 +44,19 @@ public class IntegerWithBooleanFieldEditor extends IntegerFieldEditor {
super.doFillIntoGrid(parent, numColumns);
}
@Override
public int getNumberOfControls() {
return super.getNumberOfControls() + 1;
}
@Override
protected void adjustForNumColumns(int numColumns) {
// the checkbox uses one column
super.adjustForNumColumns(numColumns - 1);
}
private Button getCheckboxControl(Composite parent) {
if (fCheckbox == null) {
fCheckbox= new Button(parent, SWT.CHECK);
Composite inner= new Composite(parent, SWT.NULL);
final GridLayout layout= new GridLayout(2, false);
layout.marginWidth = 0;
inner.setLayout(layout);
fCheckbox= new Button(inner, SWT.CHECK);
fCheckbox.setFont(parent.getFont());
fCheckbox.setText(getLabelText());
// create and hide label from base class
Label label = getLabelControl(inner);
label.setText(""); //$NON-NLS-1$
label.setVisible(false);
fCheckbox.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
@ -65,11 +66,22 @@ public class IntegerWithBooleanFieldEditor extends IntegerFieldEditor {
}
});
} else {
checkParent(fCheckbox, parent);
checkParent(fCheckbox.getParent(), parent);
}
return fCheckbox;
}
@Override
public Label getLabelControl(Composite parent) {
final Label label= getLabelControl();
if (label == null) {
return super.getLabelControl(parent);
} else {
checkParent(label.getParent(), parent);
}
return label;
}
protected void valueChanged(boolean oldValue, boolean newValue) {
setPresentsDefaultValue(false);
if (oldValue != newValue) {

View file

@ -20,8 +20,12 @@ class MessagesForPreferences extends NLS {
public static String DsfDebugPreferencePage_description;
public static String DsfDebugPreferencePage_limitStackFrames_label;
public static String DsfDebugPreferencePage_minStepInterval_label;
public static String DsfDebugPreferencePage_performanceGroup_label;
public static String DsfDebugPreferencePage_syncStepping_label;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, MessagesForPreferences.class);

View file

@ -14,8 +14,10 @@ import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
/**
* A string field editor with an enablement check box.
@ -47,20 +49,19 @@ public class StringWithBooleanFieldEditor extends StringFieldEditor {
super.doFillIntoGrid(parent, numColumns);
}
@Override
public int getNumberOfControls() {
return super.getNumberOfControls() + 1;
}
@Override
protected void adjustForNumColumns(int numColumns) {
// the checkbox uses one column
super.adjustForNumColumns(numColumns - 1);
}
private Button getCheckboxControl(Composite parent) {
if (fCheckbox == null) {
fCheckbox= new Button(parent, SWT.CHECK);
Composite inner= new Composite(parent, SWT.NULL);
final GridLayout layout= new GridLayout(2, false);
layout.marginWidth = 0;
inner.setLayout(layout);
fCheckbox= new Button(inner, SWT.CHECK);
fCheckbox.setFont(parent.getFont());
fCheckbox.setText(getLabelText());
// create and hide label from base class
Label label = getLabelControl(inner);
label.setText(""); //$NON-NLS-1$
label.setVisible(false);
fCheckbox.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
@ -70,11 +71,22 @@ public class StringWithBooleanFieldEditor extends StringFieldEditor {
}
});
} else {
checkParent(fCheckbox, parent);
checkParent(fCheckbox.getParent(), parent);
}
return fCheckbox;
}
@Override
public Label getLabelControl(Composite parent) {
final Label label= getLabelControl();
if (label == null) {
return super.getLabelControl(parent);
} else {
checkParent(label.getParent(), parent);
}
return label;
}
protected void valueChanged(boolean oldValue, boolean newValue) {
setPresentsDefaultValue(false);
if (oldValue != newValue) {

View file

@ -11,4 +11,6 @@
DsfDebugPreferencePage_description=General settings for debugging with DSF:
DsfDebugPreferencePage_limitStackFrames_label=Limit number of stack frames to
DsfDebugPreferencePage_minStepInterval_label=Minimum interval between steps (in milliseconds)
DsfDebugPreferencePage_performanceGroup_label=Performance
DsfDebugPreferencePage_syncStepping_label=Synchronize stepping speed with UI updates

View file

@ -12,7 +12,9 @@ package org.eclipse.dd.dsf.debug.ui;
import org.eclipse.debug.ui.IDebugUIConstants;
/**
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IDsfDebugUIConstants {
/**
@ -60,15 +62,33 @@ public interface IDsfDebugUIConstants {
* Integer preference to control the maximum amount of stack frames to
* retrieve from the backend. Default value is 10.
* @see {@link #PREF_STACK_FRAME_LIMIT_ENABLE}
*
* @since 1.1
*/
public static final String PREF_STACK_FRAME_LIMIT = "stackFrameLimit"; //$NON-NLS-1$
/**
* Boolean preference whether to apply the stack frame limit preference.
* Boolean preference whether to apply the stack frame limit preference. Default is <code>true</code>.
* @see {@link #PREF_STACK_FRAME_LIMIT}
*
* @since 1.1
*/
public static final String PREF_STACK_FRAME_LIMIT_ENABLE = "stackFrameLimitEnable"; //$NON-NLS-1$
/**
* Boolean preference whether to keep stepping speed in sync with UI updates. Default is <code>true</code>.
*
* @since 1.1
*/
public static final String PREF_SYNCHRONIZED_STEPPING_ENABLE = "synchronizedSteppingEnable"; //$NON-NLS-1$
/**
* Integer preference to enforce a minimum time interval between steps. Default is <code>0</code>.
*
* @since 1.1
*/
public static final String PREF_MIN_STEP_INTERVAL= "minStepInterval"; //$NON-NLS-1$
/**
* Help prefixes.
*/
@ -85,5 +105,8 @@ public interface IDsfDebugUIConstants {
public static final String DETAIL_PANE_WORD_WRAP_ACTION = PREFIX + "detail_pane_word_wrap_action_context"; //$NON-NLS-1$
public static final String DETAIL_PANE_MAX_LENGTH_ACTION = PREFIX + "detail_pane_max_length_action_context"; //$NON-NLS-1$
/**
* @since 1.1
*/
public static final String PREFERENCE_PAGE= PREFIX + "preference_page_context"; //$NON-NLS-1$
}

View file

@ -58,5 +58,7 @@ public class PreferenceInitializer extends AbstractPreferenceInitializer {
*/
prefs.setDefault(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, 10);
prefs.setDefault(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE, true);
}
prefs.setDefault(IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE, true);
prefs.setDefault(IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL, 0);
}
}

View file

@ -15,8 +15,10 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
import org.eclipse.dd.dsf.concurrent.Immutable;
import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.IStepQueueManager;
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.dd.dsf.service.DsfServicesTracker;
@ -33,10 +35,36 @@ public abstract class DsfCommandRunnable extends DsfRunnable {
public IRunControl getRunControl() {
return fTracker.getService(IRunControl.class);
}
public StepQueueManager getStepQueueMgr() {
/**
* @deprecated Use {@link #getStepQueueManager()} instead.
*/
@Deprecated
public StepQueueManager getStepQueueMgr() {
return fTracker.getService(StepQueueManager.class);
}
/**
* @since 1.1
*/
public IStepQueueManager getStepQueueManager() {
// for backwards compatibility
IStepQueueManager mgr= getStepQueueMgr();
if (mgr != null) {
return mgr;
}
return getSteppingController();
}
/**
* @since 1.1
*/
public SteppingController getSteppingController() {
if (fContext != null) {
return (SteppingController) fContext.getAdapter(SteppingController.class);
}
return null;
}
public DsfCommandRunnable(DsfServicesTracker servicesTracker, Object element, IDebugCommandRequest request) {
fTracker = servicesTracker;
if (element instanceof IDMVMContext) {
@ -56,7 +84,7 @@ public abstract class DsfCommandRunnable extends DsfRunnable {
}
if (getContext() == null) {
fRequest.setStatus(makeError("Selected object does not support run control.", null)); //$NON-NLS-1$
} else if (getRunControl() == null || getStepQueueMgr() == null) {
} else if (getRunControl() == null || getStepQueueManager() == null) {
fRequest.setStatus(makeError("Run Control not available", null)); //$NON-NLS-1$
} else {
doExecute();

View file

@ -49,7 +49,7 @@ public class DsfStepIntoCommand implements IStepIntoHandler {
final StepType stepType= getStepType();
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
@Override public void doExecute() {
getStepQueueMgr().canEnqueueStep(
getStepQueueManager().canEnqueueStep(
getContext(), stepType,
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
@Override
@ -71,7 +71,7 @@ public class DsfStepIntoCommand implements IStepIntoHandler {
final StepType stepType= getStepType();
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
@Override public void doExecute() {
getStepQueueMgr().enqueueStep(getContext(), stepType);
getStepQueueManager().enqueueStep(getContext(), stepType);
}
});
return true;

View file

@ -49,7 +49,7 @@ public class DsfStepOverCommand implements IStepOverHandler {
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
final StepType stepType= getStepType();
@Override public void doExecute() {
getStepQueueMgr().canEnqueueStep(
getStepQueueManager().canEnqueueStep(
getContext(), stepType,
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
@Override
@ -71,7 +71,7 @@ public class DsfStepOverCommand implements IStepOverHandler {
final StepType stepType= getStepType();
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
@Override public void doExecute() {
getStepQueueMgr().enqueueStep(getContext(), stepType);
getStepQueueManager().enqueueStep(getContext(), stepType);
}
});
return true;

View file

@ -46,7 +46,7 @@ public class DsfStepReturnCommand implements IStepReturnHandler {
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
@Override public void doExecute() {
getStepQueueMgr().canEnqueueStep(
getStepQueueManager().canEnqueueStep(
getContext(), StepType.STEP_RETURN,
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
@Override
@ -67,7 +67,7 @@ public class DsfStepReturnCommand implements IStepReturnHandler {
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
@Override public void doExecute() {
getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_RETURN);
getStepQueueManager().enqueueStep(getContext(), StepType.STEP_RETURN);
}
});
return true;

View file

@ -33,10 +33,14 @@ import org.eclipse.dd.dsf.concurrent.Query;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController.ISteppingControlParticipant;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController.SteppingTimedOutEvent;
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.IStack;
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData;
@ -86,7 +90,7 @@ import org.eclipse.ui.texteditor.ITextEditor;
* dispatch thread to synchronize access to the state data of the running jobs.
*/
@ThreadSafe
public class DsfSourceDisplayAdapter implements ISourceDisplay
public class DsfSourceDisplayAdapter implements ISourceDisplay, ISteppingControlParticipant
{
/**
* A job to perform source lookup on the given DMC.
@ -412,8 +416,16 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay
private DisplayJob fPendingDisplayJob;
private ClearingJob fRunningClearingJob;
private List<IRunControl.IExecutionDMContext> fPendingExecDmcsToClear = new LinkedList<IRunControl.IExecutionDMContext>();
private SteppingController fController;
public DsfSourceDisplayAdapter(DsfSession session, ISourceLookupDirector sourceLocator) {
this(session, sourceLocator, null);
}
/**
* @since 1.1
*/
public DsfSourceDisplayAdapter(DsfSession session, ISourceLookupDirector sourceLocator, SteppingController controller) {
fSession = session;
fExecutor = session.getExecutor();
fServicesTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
@ -424,9 +436,18 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay
fIPManager = new InstructionPointerManager();
fSession.addServiceEventListener(this, null);
fController = controller;
if (fController != null) {
fController.addSteppingControlParticipant(this);
}
}
public void dispose() {
if (fController != null) {
fController.removeSteppingControlParticipant(this);
fController = null;
}
fSession.removeServiceEventListener(this);
fServicesTracker.dispose();
fSourceLookup.removeParticipants(new ISourceLookupParticipant[] {fSourceLookupParticipant});
@ -470,7 +491,9 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay
private void startLookupJob(final IDMContext dmc, final IWorkbenchPage page) {
// If there is a previous lookup job running, cancel it.
if (fRunningLookupJob != null) {
fRunningLookupJob.cancel();
if (fRunningLookupJob.cancel()) {
doneSourceLookup(fRunningLookupJob.getDmc());
}
}
fRunningLookupJob = new LookupJob(dmc, page);
@ -500,8 +523,22 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay
fRunningDisplayJob = nextDisplayJob;
fRunningDisplayJob.schedule();
}
doneSourceLookup(lookupResult.getDmc());
}
private void doneSourceLookup(IDMContext context) {
if (fController != null) {
// indicate completion of step
final IExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
if (dmc != null) {
fController.getExecutor().execute(new DsfRunnable() {
public void run() {
fController.doneStepping(dmc, DsfSourceDisplayAdapter.this);
};
});
}
}
}
private void serviceDisplayAndClearingJobs() {
if (!fPendingExecDmcsToClear.isEmpty()) {
@ -557,16 +594,18 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay
startAnnotationClearingJob(e.getDMContext());
}
@DsfServiceEventHandler
public void eventDispatched(SteppingTimedOutEvent e) {
startAnnotationClearingJob(e.getDMContext());
}
@DsfServiceEventHandler
public void eventDispatched(StepQueueManager.ISteppingTimedOutEvent e) {
startAnnotationClearingJob(e.getDMContext());
}
}
@DsfServiceEventHandler
public void eventDispatched(IRunControl.ISuspendedDMEvent e) {
if (e.getReason() == StateChangeReason.STEP) {
startAnnotationClearingJob(e.getDMContext());
}
fPrevModelContext = null;
}
}

View file

@ -21,6 +21,7 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.IStack;
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.text.Position;
@ -37,7 +38,17 @@ import org.eclipse.ui.texteditor.ITextEditor;
@ThreadSafe
class InstructionPointerManager {
/**
* Current instruction pointer annotation type.
*/
private static final String ID_CURRENT_IP= "org.eclipse.dd.debug.currentIP"; //$NON-NLS-1$
/**
* Secondary instruction pointer annotation type.
*/
private static final String ID_SECONDARY_IP= "org.eclipse.dd.debug.secondaryIP"; //$NON-NLS-1$
/**
* Editor annotation object for instruction pointers.
*/
static class IPAnnotation extends Annotation {
@ -61,7 +72,7 @@ class InstructionPointerManager {
fFrame = frame;
fImage = image;
}
/**
* Returns this annotation's image.
*
@ -170,15 +181,19 @@ class InstructionPointerManager {
String text;
Image image;
if (isTopFrame) {
id = "org.eclipse.dd.debug.currentIP"; //$NON-NLS-1$
id = ID_CURRENT_IP;
text = "Debug Current Instruction Pointer"; //$NON-NLS-1$
image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER_TOP);
} else {
id = "org.eclipse.dd.debug.secondaryIP"; //$NON-NLS-1$
id = ID_SECONDARY_IP;
text = "Debug Call Stack"; //$NON-NLS-1$
image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER);
}
if (isTopFrame) {
// remove other top-frame IP annotation(s) for this execution-context
removeAnnotations(DMContexts.getAncestorOfType(frame.getParents()[0], IExecutionDMContext.class));
}
Annotation annotation = new IPAnnotation(frame, id, text, image);
// Add the annotation at the position to the editor's annotation model.
@ -202,10 +217,28 @@ class InstructionPointerManager {
removeAnnotation(wrapper.getTextEditor(), wrapper.getAnnotation());
wrapperItr.remove();
}
}
}
}
}
/**
* Remove all top-frame annotations associated with the specified debug target that this class
* is tracking.
*/
public void removeTopFrameAnnotations(IRunControl.IExecutionDMContext execDmc) {
// Retrieve the mapping of threads to context lists
synchronized(fAnnotationWrappers) {
for (Iterator<AnnotationWrapper> wrapperItr = fAnnotationWrappers.iterator(); wrapperItr.hasNext();) {
AnnotationWrapper wrapper = wrapperItr.next();
if (DMContexts.isAncestorOf(wrapper.getFrameDMC(), execDmc)
&& ID_CURRENT_IP.equals(wrapper.getAnnotation().getType())) {
removeAnnotation(wrapper.getTextEditor(), wrapper.getAnnotation());
wrapperItr.remove();
}
}
}
}
/** Removes all annotations tracked by this manager */
public void removeAllAnnotations() {
synchronized(fAnnotationWrappers) {

View file

@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.debug.service;
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.dd.dsf.debug.service.IRunControl.StepType;
import org.eclipse.dd.dsf.service.DsfSession;
/**
* @since 1.1
*/
@ConfinedToDsfExecutor("getSession().getExecutor()")
public interface IStepQueueManager {
/**
* Returns the session for which this step queue manager is used.
*/
public DsfSession getSession();
/**
* Checks whether a step command can be queued up for given context.
*/
public abstract void canEnqueueStep(IExecutionDMContext execCtx, StepType stepType, DataRequestMonitor<Boolean> rm);
/**
* Adds a step command to the execution queue for given context.
* @param execCtx Execution context that should perform the step.
* @param stepType Type of step to execute.
*/
public abstract void enqueueStep(final IExecutionDMContext execCtx, final StepType stepType);
}

View file

@ -41,11 +41,14 @@ import org.osgi.framework.BundleContext;
* is used, other service implementations, such as stack and expressions, can
* use it to avoid requesting data from debugger back end if another step is
* about to be executed.
*
* @deprecated The functionality has been integrated in the UI layer.
*/
public class StepQueueManager extends AbstractDsfService
@Deprecated
public class StepQueueManager extends AbstractDsfService implements IStepQueueManager
{
/**
* Amount of time in miliseconds, that it takes the ISteppingTimedOutEvent
* Amount of time in milliseconds, that it takes the ISteppingTimedOutEvent
* event to be issued after a step is started.
* @see ISteppingTimedOutEvent
*/
@ -113,9 +116,9 @@ public class StepQueueManager extends AbstractDsfService
return DsfDebugPlugin.getBundleContext();
}
/**
* Checks whether a step command can be queued up for given context.
*/
/*
* @see org.eclipse.dd.dsf.debug.service.IStepQueueManager#canEnqueueStep(org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext, org.eclipse.dd.dsf.debug.service.IRunControl.StepType, org.eclipse.dd.dsf.concurrent.DataRequestMonitor)
*/
public void canEnqueueStep(IExecutionDMContext execCtx, StepType stepType, DataRequestMonitor<Boolean> rm) {
if (doCanEnqueueStep(execCtx, stepType)) {
rm.setData(true);
@ -139,11 +142,9 @@ public class StepQueueManager extends AbstractDsfService
return stepQueue.size();
}
/**
* Adds a step command to the execution queue for given context.
* @param execCtx Execution context that should perform the step.
* @param stepType Type of step to execute.
*/
/*
* @see org.eclipse.dd.dsf.debug.service.IStepQueueManager#enqueueStep(org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext, org.eclipse.dd.dsf.debug.service.IRunControl.StepType)
*/
public void enqueueStep(final IExecutionDMContext execCtx, final StepType stepType) {
fRunControl.canStep(
execCtx, stepType, new DataRequestMonitor<Boolean>(getExecutor(), null) {

View file

@ -10,14 +10,20 @@
*******************************************************************************/
package org.eclipse.dd.dsf.ui.viewmodel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
@ -28,6 +34,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
import org.eclipse.jface.viewers.TreePath;
/**
* Base implementation for View Model Adapters. The implementation uses
@ -38,10 +45,140 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
@SuppressWarnings("restriction")
abstract public class AbstractVMAdapter implements IVMAdapter
{
private boolean fDisposed;
/**
* Interface for a viewer update which can be "monitored".
*/
interface IMonitoredUpdate extends IViewerUpdate {
boolean isDone();
void setMonitor(RequestMonitor monitor);
}
/**
* Wraps an IViewerUpdate to add a request monitor.
*/
abstract static class MonitoredUpdate implements IMonitoredUpdate {
protected IViewerUpdate fDelegate;
private boolean fIsDone;
private RequestMonitor fMonitor;
MonitoredUpdate(IViewerUpdate update) {
fDelegate = update;
}
public boolean isDone() {
return fIsDone;
}
public void setMonitor(RequestMonitor monitor) {
fMonitor = monitor;
if (fIsDone) {
monitor.done();
}
}
public Object getElement() {
return fDelegate.getElement();
}
public TreePath getElementPath() {
return fDelegate.getElementPath();
}
public IPresentationContext getPresentationContext() {
return fDelegate.getPresentationContext();
}
public Object getViewerInput() {
return fDelegate.getViewerInput();
}
public void cancel() {
fDelegate.cancel();
if (!fIsDone) {
fIsDone = true;
if (fMonitor != null) {
fMonitor.done();
}
}
}
public void done() {
fDelegate.done();
if (!fIsDone) {
fIsDone = true;
if (fMonitor != null) {
fMonitor.done();
}
}
}
public IStatus getStatus() {
return fDelegate.getStatus();
}
public boolean isCanceled() {
return fDelegate.isCanceled();
}
public void setStatus(IStatus status) {
fDelegate.setStatus(status);
}
}
static class MonitoredChildrenUpdate extends MonitoredUpdate implements IChildrenUpdate {
public MonitoredChildrenUpdate(IChildrenUpdate update) {
super(update);
}
public int getLength() {
return ((IChildrenUpdate)fDelegate).getLength();
}
public int getOffset() {
return ((IChildrenUpdate)fDelegate).getOffset();
}
public void setChild(Object child, int offset) {
((IChildrenUpdate)fDelegate).setChild(child, offset);
}
}
static class MonitoredHasChildrenUpdate extends MonitoredUpdate implements IHasChildrenUpdate {
public MonitoredHasChildrenUpdate(IHasChildrenUpdate update) {
super(update);
}
public void setHasChilren(boolean hasChildren) {
((IHasChildrenUpdate)fDelegate).setHasChilren(hasChildren);
}
}
static class MonitoredChildrenCountUpdate extends MonitoredUpdate implements IChildrenCountUpdate {
public MonitoredChildrenCountUpdate(IChildrenCountUpdate update) {
super(update);
}
public void setChildCount(int numChildren) {
((IChildrenCountUpdate)fDelegate).setChildCount(numChildren);
}
}
private boolean fDisposed;
private final Map<IPresentationContext, IVMProvider> fViewModelProviders =
Collections.synchronizedMap( new HashMap<IPresentationContext, IVMProvider>() );
Collections.synchronizedMap( new HashMap<IPresentationContext, IVMProvider>() );
/**
* List of IViewerUpdates pending after processing an event.
*/
private final List<IMonitoredUpdate> fPendingUpdates = new ArrayList<IMonitoredUpdate>();
/**
* Constructor for the View Model session. It is tempting to have the
@ -70,6 +207,16 @@ abstract public class AbstractVMAdapter implements IVMAdapter
}
}
/**
* Enumerate the VM providers.
* @return An instance of {@link Iterable<IVMProvider>}
*
* @since 1.1
*/
protected Iterable<IVMProvider> getVMProviderIterable() {
return fViewModelProviders.values();
}
public void dispose() {
IVMProvider[] providers = new IVMProvider[0];
synchronized(fViewModelProviders) {
@ -91,31 +238,29 @@ abstract public class AbstractVMAdapter implements IVMAdapter
}
}
/**
* @return whether this VM adapter is disposed.
*
* @since 1.1
*/
public boolean isDisposed() {
return fDisposed;
}
public void update(IHasChildrenUpdate[] updates) {
IVMProvider provider = getVMProvider(updates[0].getPresentationContext());
if (provider != null) {
updateProvider(provider, updates);
} else {
for (IViewerUpdate update : updates) {
update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
"No model provider for update " + update, null)); //$NON-NLS-1$
}
}
handleUpdate(updates);
}
public void update(IChildrenCountUpdate[] updates) {
IVMProvider provider = getVMProvider(updates[0].getPresentationContext());
if (provider != null) {
updateProvider(provider, updates);
} else {
for (IViewerUpdate update : updates) {
update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
"No model provider for update " + update, null)); //$NON-NLS-1$
}
}
handleUpdate(updates);
}
public void update(final IChildrenUpdate[] updates) {
handleUpdate(updates);
}
private void handleUpdate(IViewerUpdate[] updates) {
updates = wrapUpdates(updates);
IVMProvider provider = getVMProvider(updates[0].getPresentationContext());
if (provider != null) {
updateProvider(provider, updates);
@ -123,10 +268,11 @@ abstract public class AbstractVMAdapter implements IVMAdapter
for (IViewerUpdate update : updates) {
update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
"No model provider for update " + update, null)); //$NON-NLS-1$
update.done();
}
}
}
private void updateProvider(final IVMProvider provider, final IViewerUpdate[] updates) {
try {
provider.getExecutor().execute(new Runnable() {
@ -187,4 +333,110 @@ abstract public class AbstractVMAdapter implements IVMAdapter
*/
@ThreadSafe
abstract protected IVMProvider createViewModelProvider(IPresentationContext context);
/**
* Dispatch given event to VM providers interested in events.
*
* @since 1.1
*/
protected final void handleEvent(final Object event) {
final List<IVMEventListener> eventListeners = new ArrayList<IVMEventListener>();
aboutToHandleEvent(event);
for (IVMProvider vmProvider : getVMProviderIterable()) {
if (vmProvider instanceof IVMEventListener) {
eventListeners.add((IVMEventListener)vmProvider);
}
}
if (!eventListeners.isEmpty()) {
synchronized (fPendingUpdates) {
fPendingUpdates.clear();
}
// TODO which executor to use?
final Executor executor= eventListeners.get(0).getExecutor();
final CountingRequestMonitor crm = new CountingRequestMonitor(executor, null) {
@Override
protected void handleCompleted() {
if (isDisposed()) {
return;
}
// The event listeners have completed processing the event.
// Now monitor completion of viewer updates issued while dispatching the event
final CountingRequestMonitor updatesMonitor = new CountingRequestMonitor(executor, null) {
@Override
protected void handleCompleted() {
if (isDisposed()) {
return;
}
doneHandleEvent(event);
}
};
synchronized (fPendingUpdates) {
int pending = fPendingUpdates.size();
updatesMonitor.setDoneCount(pending);
for (IMonitoredUpdate update : fPendingUpdates) {
update.setMonitor(updatesMonitor);
}
fPendingUpdates.clear();
}
}
};
crm.setDoneCount(eventListeners.size());
for (final IVMEventListener vmEventListener : eventListeners) {
vmEventListener.getExecutor().execute(new DsfRunnable() {
public void run() {
vmEventListener.handleEvent(event, crm);
}});
}
}
}
private IViewerUpdate[] wrapUpdates(IViewerUpdate[] updates) {
if (updates.length == 0) {
return updates;
}
int i = 0;
synchronized (fPendingUpdates) {
for (IViewerUpdate update : updates) {
IMonitoredUpdate wrap= createMonitoredUpdate(update);
updates[i++] = wrap;
fPendingUpdates.add(wrap);
}
}
return updates;
}
private IMonitoredUpdate createMonitoredUpdate(IViewerUpdate update) {
if (update instanceof IChildrenCountUpdate) {
return new MonitoredChildrenCountUpdate(((IChildrenCountUpdate)update));
} else if (update instanceof IHasChildrenUpdate) {
return new MonitoredHasChildrenUpdate(((IHasChildrenUpdate)update));
} else if (update instanceof IChildrenUpdate) {
return new MonitoredChildrenUpdate(((IChildrenUpdate)update));
}
return null;
}
/**
* Given event is about to be handled.
*
* @param event
*
* @since 1.1
*/
protected void aboutToHandleEvent(final Object event) {
}
/**
* Given event has been processed by all VM event listeners.
*
* @param event
*
* @since 1.1
*/
protected void doneHandleEvent(final Object event) {
}
}

View file

@ -20,6 +20,7 @@ import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
@ -60,7 +61,7 @@ import org.eclipse.swt.widgets.Display;
* @see IVMNode
*/
@SuppressWarnings("restriction")
abstract public class AbstractVMProvider implements IVMProvider
abstract public class AbstractVMProvider implements IVMProvider, IVMEventListener
{
/** Reference to the VM adapter that owns this provider */
@ -204,8 +205,20 @@ abstract public class AbstractVMProvider implements IVMProvider
* Processes the given event in the given provider, sending model
* deltas if necessary.
*/
public void handleEvent(final Object event) {
for (final IVMModelProxy proxyStrategy : getActiveModelProxies()) {
public void handleEvent(final Object event) {
handleEvent(event, null);
}
/**
* {@inheritDoc}
* @since 1.1
*/
public void handleEvent(final Object event, RequestMonitor rm) {
CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm);
final List<IVMModelProxy> activeModelProxies= new ArrayList<IVMModelProxy>(getActiveModelProxies());
crm.setDoneCount(activeModelProxies.size());
for (final IVMModelProxy proxyStrategy : activeModelProxies) {
if (proxyStrategy.isDeltaEvent(event)) {
if (!fEventQueues.containsKey(proxyStrategy)) {
fEventQueues.put(proxyStrategy, new ModelProxyEventQueue());
@ -222,13 +235,16 @@ abstract public class AbstractVMProvider implements IVMProvider
}
}
}
crm.done();
queue.fEventQueue.add(event);
} else {
doHandleEvent(queue, proxyStrategy, event);
doHandleEvent(queue, proxyStrategy, event, crm);
}
} else {
crm.done();
}
}
// Clean up model proxies that were removed.
List<IVMModelProxy> activeProxies = getActiveModelProxies();
for (Iterator<IVMModelProxy> itr = fEventQueues.keySet().iterator(); itr.hasNext();) {
@ -237,8 +253,8 @@ abstract public class AbstractVMProvider implements IVMProvider
}
}
}
private void doHandleEvent(final ModelProxyEventQueue queue, final IVMModelProxy proxyStrategy, final Object event) {
private void doHandleEvent(final ModelProxyEventQueue queue, final IVMModelProxy proxyStrategy, final Object event, final RequestMonitor rm) {
queue.fProcessingEvent = true;
handleEvent(
proxyStrategy, event,
@ -247,8 +263,10 @@ abstract public class AbstractVMProvider implements IVMProvider
protected void handleCompleted() {
queue.fProcessingEvent = false;
if (!queue.fEventQueue.isEmpty()) {
doHandleEvent(queue, proxyStrategy, queue.fEventQueue.remove(0));
}
doHandleEvent(queue, proxyStrategy, queue.fEventQueue.remove(0), rm);
} else {
rm.done();
}
}
});
}

View file

@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.dsf.ui.viewmodel;
import java.util.concurrent.Executor;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
/**
* A listener participating in event notifications sent out from VM adapter.
*
* @since 1.1
*/
public interface IVMEventListener {
/**
* Returns the executor that needs to be used to access this event listener.
*/
public Executor getExecutor();
/**
* Process the given event and indicate completion with request monitor.
*/
public abstract void handleEvent(final Object event, RequestMonitor rm);
}

View file

@ -200,6 +200,8 @@ public class VMDelta extends ModelDelta {
*
* @param element child element
* @return corresponding delta node, or <code>null</code>
*
* @since 1.1
*/
@Override
public VMDelta getChildDelta(Object element) {

View file

@ -10,7 +10,11 @@
*******************************************************************************/
package org.eclipse.dd.dsf.ui.viewmodel.datamodel;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
@ -22,6 +26,13 @@ abstract public class AbstractDMVMAdapter extends AbstractVMAdapter
{
private final DsfSession fSession;
/**
* It is theoretically possible for a VM adapter to be disposed before it
* has a chance to register itself as event listener. This flag is used
* to avoid removing itself as listener in such situation.
*/
private boolean fRegisteredAsEventListener = false;
/**
* Constructor for the View Model session. It is tempting to have the
* adapter register itself here with the session as the model adapter, but
@ -33,12 +44,59 @@ abstract public class AbstractDMVMAdapter extends AbstractVMAdapter
public AbstractDMVMAdapter(DsfSession session) {
super();
fSession = session;
// Add ourselves as listener for DM events events.
try {
session.getExecutor().execute(new Runnable() {
public void run() {
if (DsfSession.isSessionActive(getSession().getId())) {
getSession().addServiceEventListener(AbstractDMVMAdapter.this, null);
fRegisteredAsEventListener = true;
}
}
});
} catch (RejectedExecutionException e) {
// Session shut down, not much we can do but wait to be disposed.
}
}
@Override
public void dispose() {
try {
getSession().getExecutor().execute(new Runnable() {
public void run() {
if (fRegisteredAsEventListener && getSession().isActive()) {
fSession.removeServiceEventListener(AbstractDMVMAdapter.this);
}
}
});
} catch (RejectedExecutionException e) {
// Session shut down.
}
super.dispose();
}
/**
* Returns the DSF session that this adapter is associated with.
* @return
*/
protected DsfSession getSession() { return fSession; }
/**
* Handle "data model changed" event by generating a delta object for each
* view and passing it to the corresponding view model provider. The view
* model provider is then responsible for filling-in and sending the delta
* to the viewer.
*
* @param event
*
* @since 1.1
*/
@DsfServiceEventHandler
public final void eventDispatched(final IDMEvent<?> event) {
// We're in session's executor thread (session in which the event originated).
if (isDisposed()) return;
handleEvent(event);
}
}

View file

@ -10,8 +10,6 @@
*******************************************************************************/
package org.eclipse.dd.dsf.ui.viewmodel.datamodel;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.dd.dsf.datamodel.IDMEvent;
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
@ -44,14 +42,6 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapt
abstract public class AbstractDMVMProvider extends AbstractCachingVMProvider
{
private final DsfSession fSession;
/**
* It is theoretically possible for a VMProvider to be disposed before it
* has a chance to register itself as event listener. This flag is used
* to avoid removing itself as listener in such situation.
*/
private boolean fRegisteredAsEventListener = false;
/**
* Constructs the view model provider for given DSF session. The
* constructor is thread-safe to allow VM provider to be constructed
@ -61,64 +51,16 @@ abstract public class AbstractDMVMProvider extends AbstractCachingVMProvider
public AbstractDMVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) {
super(adapter, presentationContext);
fSession = session;
// Add ourselves as listener for DM events events.
try {
session.getExecutor().execute(new Runnable() {
public void run() {
if (DsfSession.isSessionActive(getSession().getId())) {
getSession().addServiceEventListener(AbstractDMVMProvider.this, null);
fRegisteredAsEventListener = true;
}
}
});
} catch (RejectedExecutionException e) {
// Session shut down, not much we can do but wait to be disposed.
}
}
/** Called to dispose the provider. */
@Override
public void dispose() {
try {
getSession().getExecutor().execute(new Runnable() {
public void run() {
if (DsfSession.isSessionActive(getSession().getId()) && fRegisteredAsEventListener ) {
fSession.removeServiceEventListener(AbstractDMVMProvider.this);
}
}
});
} catch (RejectedExecutionException e) {
// Session shut down.
}
super.dispose();
}
public DsfSession getSession() { return fSession; }
/**
* Handle "data model changed" event by generating a delta object for each
* view and passing it to the corresponding view model provider. The view
* model provider is then responsible for filling-in and sending the delta
* to the viewer.
* @param e
* @deprecated Kept for API compatibility reasons.
* Events are now received and dispatched by the VM adapter.
*/
@DsfServiceEventHandler
@Deprecated
@DsfServiceEventHandler
public void eventDispatched(final IDMEvent<?> event) {
// We're in session's executor thread (session in which the event originated).
// Re-dispach to the view model provider executor thread and then call the
// model proxy strategy to handle the event.
if (isDisposed()) return;
try {
getExecutor().execute(new Runnable() {
public void run() {
if (isDisposed()) return;
handleEvent(event);
}
});
} catch (RejectedExecutionException e) {
// Ignore. This exception could be thrown if the provider is being
// shut down.
}
}
}

View file

@ -17,6 +17,7 @@ import java.util.Map;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.dd.dsf.concurrent.Immutable;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.DefaultDsfModelSelectionPolicyFactory;
import org.eclipse.dd.dsf.debug.ui.actions.DsfResumeCommand;
import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand;
@ -62,7 +63,7 @@ import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
{
/**
* Contains the set of adapters that are created for eacy launch instance.
* Contains the set of adapters that are created for each launch instance.
*/
@Immutable
private static class LaunchAdapterSet {
@ -84,6 +85,8 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
final IDebugModelProvider fDebugModelProvider;
final PDALaunch fLaunch;
final SteppingController fSteppingController;
private IModelSelectionPolicyFactory fModelSelectionPolicyFactory;
LaunchAdapterSet(PDALaunch launch) {
@ -91,11 +94,15 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
fLaunch = launch;
DsfSession session = launch.getSession();
// register stepping controller
fSteppingController = new SteppingController(session);
session.registerModelAdapter(SteppingController.class, fSteppingController);
// Initialize VM
fViewModelAdapter = new PDAVMAdapter(session);
fViewModelAdapter = new PDAVMAdapter(session, fSteppingController);
// Initialize source lookup
fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator());
fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator(), fSteppingController);
session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter);
// Default selection policy
@ -128,7 +135,7 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
// and debug model ID will be associated with all DMContexts from this
// session.
session.registerModelAdapter(ILaunch.class, fLaunch);
}
}
void dispose() {
DsfSession session = fLaunch.getSession();
@ -138,6 +145,9 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
session.unregisterModelAdapter(ISourceDisplay.class);
if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose();
session.unregisterModelAdapter(SteppingController.class);
fSteppingController.dispose();
session.unregisterModelAdapter(IModelSelectionPolicyFactory.class);
session.unregisterModelAdapter(IStepIntoHandler.class);

View file

@ -11,11 +11,12 @@
package org.eclipse.dd.examples.pda.ui.viewmodel;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.AbstractDebugVMAdapter;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionVMProvider;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterVMProvider;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.VariableVMProvider;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter;
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.dd.examples.pda.ui.viewmodel.launch.PDALaunchVMProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
@ -24,10 +25,10 @@ import org.eclipse.debug.ui.IDebugUIConstants;
@ThreadSafe
@SuppressWarnings("restriction")
public class PDAVMAdapter extends AbstractDMVMAdapter
public class PDAVMAdapter extends AbstractDebugVMAdapter
{
public PDAVMAdapter(DsfSession session) {
super(session);
public PDAVMAdapter(DsfSession session, SteppingController controller) {
super(session, controller);
getSession().registerModelAdapter(IColumnPresentationFactory.class, this);
}

View file

@ -13,7 +13,6 @@ package org.eclipse.dd.examples.pda.launch;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.concurrent.Sequence;
import org.eclipse.dd.dsf.debug.service.BreakpointsMediator;
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.examples.pda.service.PDABreakpointAttributeTranslator;
import org.eclipse.dd.examples.pda.service.PDABreakpoints;
@ -54,13 +53,6 @@ public class PDAServicesInitSequence extends Sequence {
fRunControl.initialize(requestMonitor);
}
},
new Step() {
@Override
public void execute(RequestMonitor requestMonitor) {
// Start the service to manage step actions.
new StepQueueManager(fSession).initialize(requestMonitor);
}
},
new Step() {
@Override
public void execute(final RequestMonitor requestMonitor) {

View file

@ -17,7 +17,6 @@ import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.concurrent.Sequence;
import org.eclipse.dd.dsf.debug.service.BreakpointsMediator;
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
import org.eclipse.dd.dsf.service.DsfServicesTracker;
import org.eclipse.dd.dsf.service.IDsfService;
import org.eclipse.dd.examples.pda.PDAPlugin;
@ -86,12 +85,6 @@ public class PDAServicesShutdownSequence extends Sequence {
shutdownService(PDABreakpoints.class, requestMonitor);
}
},
new Step() {
@Override
public void execute(RequestMonitor requestMonitor) {
shutdownService(StepQueueManager.class, requestMonitor);
}
},
new Step() {
@Override
public void execute(RequestMonitor requestMonitor) {

View file

@ -19,6 +19,7 @@ import org.eclipse.cdt.debug.core.model.ISteppingModeTarget;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.dd.dsf.concurrent.Immutable;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.DefaultDsfModelSelectionPolicyFactory;
import org.eclipse.dd.dsf.debug.ui.actions.DsfResumeCommand;
import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand;
@ -79,15 +80,20 @@ public class GdbAdapterFactory
final DsfSuspendTrigger fSuspendTrigger;
final DsfSteppingModeTarget fSteppingModeTarget;
final IModelSelectionPolicyFactory fModelSelectionPolicyFactory;
final SteppingController fSteppingController;
SessionAdapterSet(GdbLaunch launch) {
fLaunch = launch;
DsfSession session = launch.getSession();
fViewModelAdapter = new GdbViewModelAdapter(session);
// register stepping controller
fSteppingController = new SteppingController(session);
session.registerModelAdapter(SteppingController.class, fSteppingController);
fViewModelAdapter = new GdbViewModelAdapter(session, fSteppingController);
if (launch.getSourceLocator() instanceof ISourceLookupDirector) {
fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator());
fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator(), fSteppingController);
} else {
fSourceDisplayAdapter = null;
}
@ -137,7 +143,10 @@ public class GdbAdapterFactory
session.unregisterModelAdapter(ISourceDisplay.class);
if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose();
session.unregisterModelAdapter(SteppingController.class);
fSteppingController.dispose();
session.unregisterModelAdapter(ISteppingModeTarget.class);
session.unregisterModelAdapter(IStepIntoHandler.class);
session.unregisterModelAdapter(IStepOverHandler.class);
@ -147,7 +156,7 @@ public class GdbAdapterFactory
session.unregisterModelAdapter(IRestart.class);
session.unregisterModelAdapter(ITerminateHandler.class);
session.unregisterModelAdapter(IModelSelectionPolicyFactory.class);
fStepIntoCommand.dispose();
fStepOverCommand.dispose();
fStepReturnCommand.dispose();

View file

@ -11,12 +11,13 @@
package org.eclipse.dd.gdb.internal.ui.viewmodel;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.AbstractDebugVMAdapter;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionVMProvider;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules.ModulesVMProvider;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterVMProvider;
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.VariableVMProvider;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter;
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.dd.gdb.internal.ui.viewmodel.launch.LaunchVMProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
@ -28,10 +29,10 @@ import org.eclipse.debug.ui.IDebugUIConstants;
*/
@ThreadSafe
@SuppressWarnings("restriction")
public class GdbViewModelAdapter extends AbstractDMVMAdapter
public class GdbViewModelAdapter extends AbstractDebugVMAdapter
{
public GdbViewModelAdapter(DsfSession session) {
super(session);
public GdbViewModelAdapter(DsfSession session, SteppingController controller) {
super(session, controller);
getSession().registerModelAdapter(IColumnPresentationFactory.class, this);
}

View file

@ -24,7 +24,6 @@ import org.eclipse.dd.dsf.debug.service.IRegisters;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.ISourceLookup;
import org.eclipse.dd.dsf.debug.service.IStack;
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType;
@ -55,10 +54,6 @@ public class ServicesLaunchSequence extends Sequence {
fLaunch.getServiceFactory().createService(fSession, IProcesses.class).initialize(requestMonitor);
}},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
new StepQueueManager(fSession).initialize(requestMonitor);
}},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
fLaunch.getServiceFactory().createService(fSession, IMemory.class).initialize(requestMonitor);
}},