diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java index c519506f688..5fba35f857a 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java @@ -174,7 +174,6 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2 // Returns the adapter type for the launch object. if (adapterType.equals(IElementContentProvider.class)) return adapterSet.fViewModelAdapter; else if (adapterType.equals(IModelProxyFactory.class)) return adapterSet.fViewModelAdapter; - else if (adapterType.equals(IColumnPresentationFactory.class)) return adapterSet.fViewModelAdapter; else return null; } diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java.html b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java.html new file mode 100644 index 00000000000..3d98e729b68 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java.html @@ -0,0 +1,223 @@ + + + +PDAAdapterFactory.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2006 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *******************************************************************************/
+ 11: package org.eclipse.dd.examples.pda.ui;
+
+ 13: import java.util.Collections;
+ 14: import java.util.HashMap;
+ 15: import java.util.Map;
+
+ 17: import org.eclipse.core.runtime.IAdapterFactory;
+ 18: import org.eclipse.dd.dsf.concurrent.Immutable;
+ 19: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
+ 20: import org.eclipse.dd.dsf.debug.ui.actions.DsfResumeCommand;
+ 21: import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand;
+ 22: import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand;
+ 23: import org.eclipse.dd.dsf.debug.ui.actions.DsfStepReturnCommand;
+ 24: import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand;
+ 25: import org.eclipse.dd.dsf.debug.ui.sourcelookup.MISourceDisplayAdapter;
+ 26: import org.eclipse.dd.dsf.service.DsfSession;
+ 27: import org.eclipse.dd.examples.pda.PDAPlugin;
+ 28: import org.eclipse.dd.examples.pda.launch.PDALaunch;
+ 29: import org.eclipse.dd.examples.pda.ui.actions.PDATerminateCommand;
+ 30: import org.eclipse.dd.examples.pda.ui.viewmodel.PDAVMAdapter;
+ 31: import org.eclipse.debug.core.DebugPlugin;
+ 32: import org.eclipse.debug.core.ILaunch;
+ 33: import org.eclipse.debug.core.ILaunchesListener2;
+ 34: import org.eclipse.debug.core.commands.IResumeHandler;
+ 35: import org.eclipse.debug.core.commands.IStepIntoHandler;
+ 36: import org.eclipse.debug.core.commands.IStepOverHandler;
+ 37: import org.eclipse.debug.core.commands.IStepReturnHandler;
+ 38: import org.eclipse.debug.core.commands.ISuspendHandler;
+ 39: import org.eclipse.debug.core.commands.ITerminateHandler;
+ 40: import org.eclipse.debug.core.model.IDebugModelProvider;
+ 41: import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
+ 42: import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
+ 43: import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
+ 44: import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
+ 45: import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
+
+ 47: /**
+ 48:  * The adapter factory is the central point of control of view model and other
+ 49:  * UI adapters of a DSF-based debugger.  As new launches are created and 
+ 50:  * old ones removed, this factory manages the life cycle of the associated
+ 51:  * UI adapters.    
+ 52:  * <p>
+ 53:  * As a platform adapter factory, this factory only  provides adapters for
+ 54:  * the launch object.  Adapters for all other objects in the DSF model hierarchy
+ 55:  * are registered with the DSF session. 
+ 56:  * </p>
+ 57:  */
+ 58: @ThreadSafe
+ 59: @SuppressWarnings({"restriction"})
+ 60: public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
+ 61: {
+ 62:     /**
+ 63:      * Contains the set of adapters that are created for eacy launch instance.
+ 64:      */
+ 65:     @Immutable
+ 66:     private static class LaunchAdapterSet {
+ 67:         // View Model adapter
+ 68:         final PDAVMAdapter fViewModelAdapter;
+ 69:         
+ 70:         // Source lookup and positioning adapter
+ 71:         final MISourceDisplayAdapter fSourceDisplayAdapter;
+ 72:         
+ 73:         // Command adapters
+ 74:         final DsfStepIntoCommand fStepIntoCommand;
+ 75:         final DsfStepOverCommand fStepOverCommand;
+ 76:         final DsfStepReturnCommand fStepReturnCommand;
+ 77:         final DsfSuspendCommand fSuspendCommand;
+ 78:         final DsfResumeCommand fResumeCommand;
+ 79:         final PDATerminateCommand fTerminateCommand;
+ 80:         
+ 81:         // Adapters for integration with other UI actions
+ 82:         final IDebugModelProvider fDebugModelProvider;
+ 83:         final PDALaunch fLaunch;
+
+ 85:         LaunchAdapterSet(PDALaunch launch) {
+ 86:             // Initialize launch and session.
+ 87:             fLaunch = launch;
+ 88:             DsfSession session = launch.getSession();
+ 89:             
+ 90:             // Initialize VM
+ 91:             fViewModelAdapter = new PDAVMAdapter(session);
+
+ 93:             // Initialize source lookup
+ 94:             fSourceDisplayAdapter = new MISourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator());
+ 95:             session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter);
+ 96:             
+ 97:             // Initialize retargetable command handler.
+ 98:             fStepIntoCommand = new DsfStepIntoCommand(session);
+ 99:             fStepOverCommand = new DsfStepOverCommand(session);
+100:             fStepReturnCommand = new DsfStepReturnCommand(session);
+101:             fSuspendCommand = new DsfSuspendCommand(session);
+102:             fResumeCommand = new DsfResumeCommand(session);
+103:             fTerminateCommand = new PDATerminateCommand(session);
+104:             session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand);
+105:             session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand);
+106:             session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand);
+107:             session.registerModelAdapter(ISuspendHandler.class, fSuspendCommand);
+108:             session.registerModelAdapter(IResumeHandler.class, fResumeCommand);
+109:             session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand);
+
+111:             // Initialize debug model provider
+112:             fDebugModelProvider = new IDebugModelProvider() {
+113:                 public String[] getModelIdentifiers() {
+114:                     return new String[] { PDAPlugin.ID_PDA_DEBUG_MODEL };
+115:                 }
+116:             };
+117:             session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider);
+118:             
+119:             // Register the launch as an adapter This ensures that the launch, 
+120:             // and debug model ID will be associated with all DMContexts from this 
+121:             // session.  
+122:             session.registerModelAdapter(ILaunch.class, fLaunch);
+123:         }
+124:         
+125:         void dispose() {
+126:             DsfSession session = fLaunch.getSession();
+
+128:             fViewModelAdapter.dispose();
+
+130:             session.unregisterModelAdapter(ISourceDisplay.class);
+131:             if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose();
+132:             
+133:             session.unregisterModelAdapter(IStepIntoHandler.class);
+134:             session.unregisterModelAdapter(IStepOverHandler.class);
+135:             session.unregisterModelAdapter(IStepReturnHandler.class);
+136:             session.unregisterModelAdapter(ISuspendHandler.class);
+137:             session.unregisterModelAdapter(IResumeHandler.class);
+138:             session.unregisterModelAdapter(ITerminateHandler.class);            
+139:             fStepIntoCommand.dispose();
+140:             fStepOverCommand.dispose();
+141:             fStepReturnCommand.dispose();
+142:             fSuspendCommand.dispose();
+143:             fResumeCommand.dispose();
+144:             fTerminateCommand.dispose();
+145:         }        
+146:     }        
+
+148:     private Map<PDALaunch, LaunchAdapterSet> fLaunchAdapterSets = 
+149:         Collections.synchronizedMap(new HashMap<PDALaunch, LaunchAdapterSet>());
+150:     
+151:     public PDAAdapterFactory() {
+152:         DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
+153:     }
+
+155:     // This IAdapterFactory method returns adapters for the PDA launch object only.  
+156:     @SuppressWarnings("unchecked") // IAdapterFactory is Java 1.3
+157:     public Object getAdapter(Object adaptableObject, Class adapterType) {
+158:         if (!(adaptableObject instanceof PDALaunch)) return null; 
+
+160:         PDALaunch launch = (PDALaunch)adaptableObject;
+
+162:         // Find the correct set of adapters based on the launch.  If not found
+163:         // it means that we have a new launch, and we have to create a 
+164:         // new set of adapters. 
+165:         LaunchAdapterSet adapterSet;
+166:         synchronized(fLaunchAdapterSets) {
+167:             adapterSet = fLaunchAdapterSets.get(launch);
+168:             if (adapterSet == null) {
+169:                 adapterSet = new LaunchAdapterSet(launch);
+170:                 fLaunchAdapterSets.put(launch, adapterSet);
+171:             }
+172:         }
+173:         
+174:         // Returns the adapter type for the launch object.
+175:         if (adapterType.equals(IElementContentProvider.class)) return adapterSet.fViewModelAdapter;
+176:         else if (adapterType.equals(IModelProxyFactory.class)) return adapterSet.fViewModelAdapter;
+177:         else return null;
+178:     }
+
+180:     @SuppressWarnings("unchecked") // IAdapterFactory is Java 1.3
+181:     public Class[] getAdapterList() {
+182:         return new Class[] { IElementContentProvider.class, IModelProxyFactory.class, IColumnPresentationFactory.class };
+183:     }
+
+185:     public void launchesRemoved(ILaunch[] launches) {
+186:         // Dispose the set of adapters for a launch only after the launch is 
+187:         // removed from the view.  If the launch is terminated, the adapters
+188:         // are still needed to populate the contents of the view.
+189:         for (ILaunch launch : launches) {
+190:             if (launch instanceof PDALaunch) {
+191:                 PDALaunch pdaLaunch = (PDALaunch)launch;
+192:                 synchronized(fLaunchAdapterSets) {
+193:                     if ( fLaunchAdapterSets.containsKey(pdaLaunch) ) {
+194:                         fLaunchAdapterSets.remove(pdaLaunch).dispose();
+195:                     }
+196:                 }
+197:             }                
+198:         }
+199:     }
+
+201:     public void launchesTerminated(ILaunch[] launches) {
+202:     }
+
+204:     public void launchesAdded(ILaunch[] launches) {
+205:     }
+206:     
+207:     public void launchesChanged(ILaunch[] launches) {
+208:     }
+209:     
+210: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java index ac1adb19cc3..0fe04f06fc6 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java @@ -12,13 +12,11 @@ package org.eclipse.dd.examples.pda.ui.viewmodel; import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider; -import org.eclipse.dd.dsf.debug.ui.viewmodel.modules.ModulesVMProvider; -import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterVMProvider; import org.eclipse.dd.dsf.debug.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.LaunchVMProvider; +import org.eclipse.dd.examples.pda.ui.viewmodel.launch.PDALaunchVMProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; @@ -44,11 +42,9 @@ public class PDAVMAdapter extends AbstractDMVMAdapter @Override protected AbstractDMVMProvider createViewModelProvider(IPresentationContext context) { if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) { - return new LaunchVMProvider(this, context, getSession()); + return new PDALaunchVMProvider(this, context, getSession()); } else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) { return new VariableVMProvider(this, context, getSession()); - } else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(context.getId()) ) { - return new RegisterVMProvider(this, context, getSession()); } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { return new ExpressionVMProvider(this, context, getSession()); } diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java.html b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java.html new file mode 100644 index 00000000000..3b9ea80e322 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java.html @@ -0,0 +1,66 @@ + + + +PDAVMAdapter.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2006 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *******************************************************************************/
+ 11: package org.eclipse.dd.examples.pda.ui.viewmodel;
+
+ 13: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
+ 14: import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider;
+ 15: import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMProvider;
+ 16: import org.eclipse.dd.dsf.service.DsfSession;
+ 17: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter;
+ 18: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
+ 19: import org.eclipse.dd.examples.pda.ui.viewmodel.launch.LaunchVMProvider;
+ 20: import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
+ 21: import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
+ 22: import org.eclipse.debug.ui.IDebugUIConstants;
+
+ 24: /* 
+ 25:  * 
+ 26:  */
+ 27: @ThreadSafe
+ 28: @SuppressWarnings("restriction")
+ 29: public class PDAVMAdapter extends AbstractDMVMAdapter
+ 30: {
+ 31:     public PDAVMAdapter(DsfSession session) {
+ 32:         super(session);
+ 33:         getSession().registerModelAdapter(IColumnPresentationFactory.class, this);
+ 34:     }    
+
+ 36:     @Override
+ 37:     public void dispose() {
+ 38:         getSession().unregisterModelAdapter(IColumnPresentationFactory.class);
+ 39:         super.dispose();
+ 40:     }
+ 41:     
+ 42:     @Override
+ 43:     protected AbstractDMVMProvider createViewModelProvider(IPresentationContext context) {
+ 44:         if ( IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) {
+ 45:             return new PDALaunchVMProvider(this, context, getSession()); 
+ 46:         } else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) {
+ 47:             return new VariableVMProvider(this, context, getSession());
+ 48:         } else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) {
+ 49:             return new ExpressionVMProvider(this, context, getSession());
+ 50:         } 
+ 51:         return null;
+ 52:     }    
+ 53: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java similarity index 92% rename from plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java rename to plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java index 3cbd4c36cef..44ff9952a85 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/LaunchVMProvider.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java @@ -43,11 +43,11 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont * */ @SuppressWarnings("restriction") -public class LaunchVMProvider extends AbstractDMVMProvider +public class PDALaunchVMProvider extends AbstractDMVMProvider implements IDebugEventSetListener, ILaunchesListener2 { @ThreadSafe - public LaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) + public PDALaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) { super(adapter, presentationContext, session); @@ -55,13 +55,13 @@ public class LaunchVMProvider extends AbstractDMVMProvider setRootNode(launchNode); // Launch node is a parent to the processes and program nodes. - IVMNode threadsNode = new PDAProgramVMNode(this, getSession()); + IVMNode pdaProgramNode = new PDAProgramVMNode(this, getSession()); IVMNode processesNode = new StandardProcessVMNode(this); - addChildNodes(launchNode, new IVMNode[] { threadsNode, processesNode}); + addChildNodes(launchNode, new IVMNode[] { pdaProgramNode, processesNode}); // Stack frames node is under the PDA program node. IVMNode stackFramesNode = new StackFramesVMNode(this, getSession()); - addChildNodes(threadsNode, new IVMNode[] { stackFramesNode }); + addChildNodes(pdaProgramNode, new IVMNode[] { stackFramesNode }); // Register the LaunchVM provider as a listener to debug and launch // events. These events are used by the launch and processes nodes. diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java.html b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java.html new file mode 100644 index 00000000000..0c9a409f3c6 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDALaunchVMProvider.java.html @@ -0,0 +1,149 @@ + + + +PDALaunchVMProvider.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2006 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *     Ericsson                          - Modified for new functionality        
+ 11:  *******************************************************************************/
+ 12: package org.eclipse.dd.examples.pda.ui.viewmodel.launch;
+
+ 14: import java.util.concurrent.RejectedExecutionException;
+
+ 16: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
+ 17: import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode;
+ 18: import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StackFramesVMNode;
+ 19: import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardProcessVMNode;
+ 20: import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode.LaunchesEvent;
+ 21: import org.eclipse.dd.dsf.service.DsfSession;
+ 22: import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
+ 23: import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode;
+ 24: import org.eclipse.dd.dsf.ui.viewmodel.IVMNode;
+ 25: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
+ 26: import org.eclipse.debug.core.DebugEvent;
+ 27: import org.eclipse.debug.core.DebugPlugin;
+ 28: import org.eclipse.debug.core.IDebugEventSetListener;
+ 29: import org.eclipse.debug.core.ILaunch;
+ 30: import org.eclipse.debug.core.ILaunchesListener2;
+ 31: import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
+
+
+ 34: /**
+ 35:  * View Model provider for the Launch (AKA Debug) view.  The PDA debugger is 
+ 36:  * single-threaded, so there is no need for a debug target element to be visible
+ 37:  * in the debug view.  Therefore the launch VM provider is configured with three nodes:
+ 38:  * <ul>
+ 39:  * <li> LaunchRootVMNode - This is the root of the PDA view model.</li>  
+ 40:  * <li> ThreadVMNode - Supplies the PDA program element.</li>  
+ 41:  * <li> StackFramesVMNode - Supplies the stack frame elements.</li>  
+ 42:  * <li> StandardProcessVMNode - Supplies elements representing the PDA debugger process.</li>
+ 43:  * </ul> 
+ 44:  */
+ 45: @SuppressWarnings("restriction")
+ 46: public class PDALaunchVMProvider extends AbstractDMVMProvider 
+ 47:     implements IDebugEventSetListener, ILaunchesListener2
+ 48: {
+ 49:     @ThreadSafe
+ 50:     public PDALaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) 
+ 51:     {
+ 52:         super(adapter, presentationContext, session);
+ 53:         
+ 54:         IRootVMNode launchNode = new LaunchRootVMNode(this);
+ 55:         setRootNode(launchNode);
+
+ 57:         // Launch node is a parent to the processes and program nodes.
+ 58:         IVMNode pdaProgramNode = new PDAProgramVMNode(this, getSession());
+ 59:         IVMNode processesNode = new StandardProcessVMNode(this);
+ 60:         addChildNodes(launchNode, new IVMNode[] { pdaProgramNode, processesNode});
+ 61:         
+ 62:         // Stack frames node is under the PDA program node.
+ 63:         IVMNode stackFramesNode = new StackFramesVMNode(this, getSession());
+ 64:         addChildNodes(pdaProgramNode, new IVMNode[] { stackFramesNode });
+
+ 66:         // Register the LaunchVM provider as a listener to debug and launch 
+ 67:         // events.  These events are used by the launch and processes nodes.
+ 68:         DebugPlugin.getDefault().addDebugEventListener(this);
+ 69:         DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
+ 70:     }
+ 71:     
+ 72:     
+ 73:     public void handleDebugEvents(final DebugEvent[] events) {
+ 74:         if (isDisposed()) return;
+ 75:         
+ 76:         // This method may be called on any thread.  Switch to the 
+ 77:         // view model executor thread before processing.
+ 78:         try {
+ 79:             getExecutor().execute(new Runnable() {
+ 80:                 public void run() {
+ 81:                     if (isDisposed()) return;
+ 82:     
+ 83:                     for (final DebugEvent event : events) {
+ 84:                         handleEvent(event);
+ 85:                     }
+ 86:                 }});
+ 87:         } catch (RejectedExecutionException e) {
+ 88:             // Ignore.  This exception could be thrown if the view model is being 
+ 89:             // shut down.  
+ 90:         }
+ 91:     }
+
+ 93:     @Override
+ 94:     public void dispose() {
+ 95:         DebugPlugin.getDefault().removeDebugEventListener(this);
+ 96:         DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
+ 97:         super.dispose();
+ 98:     }
+ 99:     
+100:     public void launchesAdded(ILaunch[] launches) {
+101:         handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.ADDED)); 
+102:     }
+103:     
+104:     public void launchesRemoved(ILaunch[] launches) {
+105:         handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.REMOVED)); 
+106:     }
+107:     
+108:     public void launchesChanged(ILaunch[] launches) {
+109:         handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.CHANGED)); 
+110:     }
+111:     
+112:     public void launchesTerminated(ILaunch[] launches) {
+113:         handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.TERMINATED)); 
+114:     }
+115:     
+116:     private void handleLaunchesEvent(final LaunchesEvent event) {
+117:         if (isDisposed()) return;
+118:         
+119:         // This method also may be called on any thread.  Switch to the 
+120:         // view model executor thread before processing.
+121:         try {
+122:             getExecutor().execute(new Runnable() {
+123:                 public void run() {
+124:                     if (isDisposed()) return;
+125:     
+126:                     IRootVMNode rootLayoutNode = getRootVMNode();
+127:                     if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) {
+128:                         handleEvent(event);
+129:                     }
+130:                 }});
+131:         } catch (RejectedExecutionException e) {
+132:             // Ignore.  This exception could be thrown if the view model is being 
+133:             // shut down.  
+134:         }
+135:     }
+136: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java index 16b27393312..b5ebe9f9544 100644 --- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java @@ -133,16 +133,18 @@ public class PDAProgramVMNode extends AbstractDMVMNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { - // Check if service is still available. checkService() is a convenience - // method that marks the update as failed if the needed service is not - // available. - if (!checkService(PDACommandControl.class, null, update)) return; - // Get the instance of the service. Note that there is no race condition // in getting the service since this method is called only in the - // service executor thred. + // service executor thread. final PDACommandControl commandControl = getServicesTracker().getService(PDACommandControl.class); - + + // Check if the service is available. If it is not, no elements are + // updated. + if (commandControl == null) { + handleFailedUpdate(update); + return; + } + update.setChild(createVMContext(commandControl.getProgramDMContext()), 0); update.done(); } @@ -172,8 +174,11 @@ public class PDAProgramVMNode extends AbstractDMVMNode @ConfinedToDsfExecutor("getSession().getExecutor()") private void updateProgramLabelInSessionThread(final ILabelUpdate update) { // Get a reference to the run control service. - if (!checkService(IRunControl.class, null, update)) return; final IRunControl runControl = getServicesTracker().getService(IRunControl.class); + if (runControl == null) { + handleFailedUpdate(update); + return; + } // Find the PDA program context. final PDAProgramDMContext programCtx = @@ -191,7 +196,7 @@ public class PDAProgramVMNode extends AbstractDMVMNode } update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); - // Retrieve the last state chagne reason + // Retrieve the last state change reason runControl.getExecutionData( programCtx, new DataRequestMonitor(ImmediateExecutor.getInstance(), null) diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java.html b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java.html new file mode 100644 index 00000000000..04e9f04ba22 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/launch/PDAProgramVMNode.java.html @@ -0,0 +1,303 @@ + + + +PDAProgramVMNode.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2006 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *     Ericsson                   - Modified for multi threaded functionality        
+ 11:  *******************************************************************************/
+ 12: package org.eclipse.dd.examples.pda.ui.viewmodel.launch;
+
+ 14: import java.util.concurrent.RejectedExecutionException;
+
+ 16: import org.eclipse.core.runtime.CoreException;
+ 17: import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
+ 18: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+ 19: import org.eclipse.dd.dsf.concurrent.DsfRunnable;
+ 20: import org.eclipse.dd.dsf.concurrent.ImmediateExecutor;
+ 21: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+ 22: import org.eclipse.dd.dsf.datamodel.IDMEvent;
+ 23: import org.eclipse.dd.dsf.debug.service.IRunControl;
+ 24: import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
+ 25: import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData;
+ 26: import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
+ 27: import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
+ 28: import org.eclipse.dd.dsf.service.DsfSession;
+ 29: import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMContext;
+ 30: import org.eclipse.dd.dsf.ui.viewmodel.IVMAdapter;
+ 31: import org.eclipse.dd.dsf.ui.viewmodel.IVMNode;
+ 32: import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
+ 33: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode;
+ 34: import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
+ 35: import org.eclipse.dd.examples.pda.PDAPlugin;
+ 36: import org.eclipse.dd.examples.pda.launch.PDALaunch;
+ 37: import org.eclipse.dd.examples.pda.service.PDACommandControl;
+ 38: import org.eclipse.dd.examples.pda.service.PDAProgramDMContext;
+ 39: import org.eclipse.dd.examples.pda.service.PDAStartedEvent;
+ 40: import org.eclipse.debug.core.ILaunch;
+ 41: import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
+ 42: import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
+ 43: import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
+ 44: import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
+ 45: import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
+ 46: import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
+ 47: import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
+ 48: import org.eclipse.debug.ui.DebugUITools;
+ 49: import org.eclipse.debug.ui.IDebugUIConstants;
+ 50: import org.eclipse.jface.viewers.TreePath;
+
+ 52: /**
+ 53:  * View Model node representing a PDA program. 
+ 54:  */
+ 55: @SuppressWarnings("restriction")
+ 56: public class PDAProgramVMNode extends AbstractDMVMNode 
+ 57:     implements IElementLabelProvider
+ 58: {
+ 59:     // View model context representing a terminated PDA program.
+ 60:     // It's purpose is to show a terminated program in the debug view
+ 61:     // even after the DSF session is terminated.
+ 62:     // 
+ 63:     // Note: this context does not implement the IDMVMContext
+ 64:     // interfaces, as it does not use an IDMContext as its root.
+ 65:     // 
+ 66:     // To implement comparison methods, this contexts uses the
+ 67:     // VM node object, such that two terminated program contexts
+ 68:     // from the same instance of VM node will be equal. 
+ 69:     private static class TerminatedProgramVMContext extends AbstractVMContext {
+ 70:         TerminatedProgramVMContext(IVMAdapter adapter, IVMNode node) {
+ 71:             super(adapter, node);
+ 72:         }
+ 73:         
+ 74:         @Override
+ 75:         public boolean equals(Object obj) {
+ 76:             if (obj instanceof TerminatedProgramVMContext) {
+ 77:                 TerminatedProgramVMContext context = (TerminatedProgramVMContext)obj;
+ 78:                 return getVMNode().equals(context.getVMNode());
+ 79:             }
+ 80:             return false;
+ 81:         }
+ 82:         
+ 83:         @Override
+ 84:         public int hashCode() {
+ 85:             return getVMNode().hashCode();
+ 86:         }
+ 87:     }
+ 88:     
+ 89:     public PDAProgramVMNode(AbstractDMVMProvider provider, DsfSession session) {
+ 90:         super(provider, session, IExecutionDMContext.class);
+ 91:     }
+
+ 93:     @Override
+ 94:     public void update(IHasChildrenUpdate[] updates) {
+ 95:         for (IHasChildrenUpdate update : updates) {
+ 96:             // Check if the launch is initialized.  PDA program element should 
+ 97:             // be shown only if the launch has completed initializing.
+ 98:             PDALaunch launch = findLaunchInPath(update.getElementPath());
+ 99:             update.setHasChilren(launch != null && launch.isInitialized());
+100:             update.done();
+101:         }        
+102:     }
+
+104:     @Override
+105:     public void update(IChildrenCountUpdate[] updates) {
+106:         for (IChildrenCountUpdate update : updates) {
+107:             // Check if the launch is initialized.  PDA program element should 
+108:             // be shown only if the launch has completed initializing.
+109:             PDALaunch launch = findLaunchInPath(update.getElementPath());
+110:             if (launch != null && launch.isInitialized()) {
+111:                 update.setChildCount(1);
+112:             } else {
+113:                 update.setChildCount(0);
+114:             }
+115:             update.done();
+116:         }        
+117:     }
+
+119:     @Override
+120:     public void update(IChildrenUpdate[] updates) {
+121:         for (IChildrenUpdate update : updates) {
+122:             PDALaunch launch = findLaunchInPath(update.getElementPath());
+123:             if (launch != null && launch.isInitialized() && launch.isShutDown()) {
+124:                 // If the debug session has been shut down, add a dummy 
+125:                 // VM context representing the PDA thread.
+126:                 update.setChild(new TerminatedProgramVMContext(getVMProvider().getVMAdapter(), this), 0);
+127:                 update.done();
+128:             } else {
+129:                 super.update(new IChildrenUpdate[] { update });
+130:             }
+131:         }
+132:     }
+133:     
+134:     @Override
+135:     protected void updateElementsInSessionThread(final IChildrenUpdate update) {
+136:             // Get the instance of the service.  Note that there is no race condition
+137:             // in getting the service since this method is called only in the 
+138:             // service executor thread.
+139:         final PDACommandControl commandControl = getServicesTracker().getService(PDACommandControl.class);
+
+141:         // Check if the service is available.  If it is not, no elements are 
+142:         // updated.
+143:         if (commandControl == null) {
+144:             handleFailedUpdate(update);
+145:             return;
+146:         }
+147:         
+148:         update.setChild(createVMContext(commandControl.getProgramDMContext()), 0);
+149:         update.done();
+150:     }
+
+152:     public void update(final ILabelUpdate[] updates) {
+153:         for (final ILabelUpdate update : updates) {
+154:             if (update.getElement() instanceof TerminatedProgramVMContext) {
+155:                 // If the element is a terminated program, update the label 
+156:                 // in the View Model thread.
+157:                 updateTerminatedThreadLabel(update);
+158:             } else {
+159:                 // If the element is the PDA Program context, try to switch
+160:                 // to the DSF session thread before updating the label.
+161:                 try {
+162:                     getSession().getExecutor().execute(new DsfRunnable() {
+163:                         public void run() {
+164:                             updateProgramLabelInSessionThread(update);
+165:                         }});
+166:                 } catch (RejectedExecutionException e) {
+167:                     // Acceptable race condition: DSF session terminated.
+168:                     handleFailedUpdate(update);
+169:                 }
+170:             }
+171:         }
+172:     }
+173:     
+174:     @ConfinedToDsfExecutor("getSession().getExecutor()")
+175:     private void updateProgramLabelInSessionThread(final ILabelUpdate update) {
+176:         // Get a reference to the run control service.
+177:         final IRunControl runControl = getServicesTracker().getService(IRunControl.class);
+178:         if (runControl == null) {
+179:             handleFailedUpdate(update);
+180:             return;
+181:         }
+182:         
+183:         // Find the PDA program context.
+184:         final PDAProgramDMContext programCtx = 
+185:             findDmcInPath(update.getViewerInput(), update.getElementPath(), PDAProgramDMContext.class);
+
+187:         // Call service to get current program state
+188:         final boolean isSuspended = runControl.isSuspended(programCtx);
+
+190:         // Set the program icon based on the running state of the program.
+191:         String imageKey = null;
+192:         if (isSuspended) {
+193:             imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED;
+194:         } else {
+195:             imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
+196:         }
+197:         update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0);
+
+199:         // Retrieve the last state chagne reason 
+200:         runControl.getExecutionData(
+201:             programCtx, 
+202:             new DataRequestMonitor<IExecutionDMData>(ImmediateExecutor.getInstance(), null) 
+203:             { 
+204:                 @Override
+205:                 public void handleCompleted(){
+206:                     // If the request failed, fail the udpate. 
+207:                     if (!getStatus().isOK()) {
+208:                         handleFailedUpdate(update);
+209:                         return;
+210:                     }
+211:     
+212:                     // Compose the thread name string.
+213:                     final StringBuilder builder = new StringBuilder(); 
+214:     
+215:                     builder.append("PDA [");
+216:                     builder.append(programCtx.getProgram());
+217:                     builder.append("]");
+218:                     
+219:                     if(isSuspended) {
+220:                         builder.append(" (Suspended"); 
+221:                     } else {
+222:                         builder.append(" (Running"); 
+223:                     }
+224:                     // Reason will be null before ContainerSuspendEvent is fired
+225:                     if(getData().getStateChangeReason() != null) {
+226:                         builder.append(" : "); 
+227:                         builder.append(getData().getStateChangeReason());
+228:                     }
+229:                     builder.append(")"); 
+230:                     update.setLabel(builder.toString(), 0);
+231:                     update.done();
+232:                 }
+233:             });        
+234:     }
+235:     
+236:     private void updateTerminatedThreadLabel(ILabelUpdate update) {
+237:         update.setLabel("<terminated> PDA [" + getProgramName(update) + "]", 0);
+238:         update.setImageDescriptor(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_DEBUG_TARGET_TERMINATED), 0);
+239:         update.done();
+240:     }
+
+242:     private String getProgramName(IViewerUpdate update) {
+243:         // Retrieve the program name from the launch object in the update path.
+244:         String program = "unknown program";
+245:         ILaunch launch = findLaunchInPath(update.getElementPath());
+246:         if (launch != null) {
+247:             try {
+248:                 program = launch.getLaunchConfiguration().getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, program);
+249:             } catch (CoreException e) {
+250:                 // Ignore, label will revert to default.
+251:             }
+252:         } 
+253:         return program;
+254:     }
+255:     
+256:     private PDALaunch findLaunchInPath(TreePath path) {
+257:         for (int i = 0; i < path.getSegmentCount(); i++) {
+258:             if (path.getSegment(i) instanceof PDALaunch) {
+259:                 return (PDALaunch)path.getSegment(i);
+260:             }
+261:         }
+262:         return null;
+263:     }
+
+265:     public int getDeltaFlags(Object e) {
+266:         if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) {
+267:             return IModelDelta.STATE;
+268:         } 
+269:         if (e instanceof PDAStartedEvent) {
+270:             return IModelDelta.EXPAND | IModelDelta.SELECT;
+271:         }
+272:         return IModelDelta.NO_CHANGE;
+273:     }
+
+275:     public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor rm) {
+276:         if(e instanceof IResumedDMEvent || e instanceof ISuspendedDMEvent) {
+277:             // If a suspended/resumed event is received, just update the 
+278:             // state of the program.  StackFramesVMNode will take care of 
+279:             // refreshing the stack frames.
+280:             parentDelta.addNode(createVMContext(((IDMEvent<?>)e).getDMContext()), IModelDelta.STATE);
+281:         } 
+282:         if (e instanceof PDAStartedEvent) {
+283:             // When debug session is started expand and select the program.
+284:             // If the program hits a breakpoint, the top stack frame will then
+285:             // be selected.
+286:             parentDelta.addNode(createVMContext(((PDAStartedEvent)e).getDMContext()), IModelDelta.EXPAND | IModelDelta.SELECT);            
+287:         }
+288:         rm.done();
+289:            }
+290: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java index 6341c937efe..99d726d6d2d 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java @@ -43,17 +43,19 @@ import org.eclipse.debug.core.model.ITerminate; */ @ThreadSafe public class PDALaunch extends Launch - implements ITerminate +implements ITerminate { // DSF executor and session. Both are created and shutdown by the launch. private final DefaultDsfExecutor fExecutor; private final DsfSession fSession; // Objects used to track the status of the DSF session. - private Sequence fInitializationSequence = null; private boolean fInitialized = false; private boolean fShutDown = false; + @ConfinedToDsfExecutor("getSession().getExecutor()") + private Sequence fInitializationSequence = null; + /** * Launch constructor creates the launch for given parameters. The * constructor also creates a DSF session and an executor, so that @@ -90,7 +92,7 @@ public class PDALaunch extends Launch { // Double-check that we're being called in the correct thread. assert fExecutor.isInExecutorThread(); - + // Check if shutdownServices() was called already, which would be // highly unusual, but if so we don't need to do anything except set // the initialized flag. @@ -100,51 +102,47 @@ public class PDALaunch extends Launch return; } } - + // Register the launch as listener for services events. fSession.addServiceEventListener(PDALaunch.this, null); - - // Initialize the fInitializationSequence attribute in a synchronized - // block, because it may be accessed in another thread by shutdown(). + // The initialization sequence is stored in a field to allow it to be // canceled if shutdownServices() is called before the sequence // completes. - synchronized(this) { - fInitializationSequence = new PDAServicesInitSequence( - getSession(), program, requestPort, eventPort, - new RequestMonitor(ImmediateExecutor.getInstance(), rm) { - @Override - protected void handleCompleted() { - // Set the initialized flag and check whether the - // shutdown flag is set. Access the flags in a - // synchronized section as these flags can be accessed - // on any thread. - boolean doShutdown = false; - synchronized (this) { - fInitialized = true; - fInitializationSequence = null; - if (fShutDown) { - doShutdown = true; - } + fInitializationSequence = new PDAServicesInitSequence( + getSession(), program, requestPort, eventPort, + new RequestMonitor(ImmediateExecutor.getInstance(), rm) { + @Override + protected void handleCompleted() { + // Set the initialized flag and check whether the + // shutdown flag is set. Access the flags in a + // synchronized section as these flags can be accessed + // on any thread. + boolean doShutdown = false; + synchronized (this) { + fInitialized = true; + fInitializationSequence = null; + if (fShutDown) { + doShutdown = true; } - - if (doShutdown) { - // If shutdownServices() was already called, start the - // shutdown sequence now. - doShutdown(rm); - } else { - // If there was an error in the startup sequence, - // report the error to the client. - if (getStatus().getSeverity() == IStatus.ERROR) { - rm.setStatus(getStatus()); - } - rm.done(); - } - fireChanged(); } - }); - } - + + if (doShutdown) { + // If shutdownServices() was already called, start the + // shutdown sequence now. + doShutdown(rm); + } else { + // If there was an error in the startup sequence, + // report the error to the client. + if (getStatus().getSeverity() == IStatus.ERROR) { + rm.setStatus(getStatus()); + } + rm.done(); + } + fireChanged(); + } + }); + // Finally, execute the sequence. getSession().getExecutor().execute(fInitializationSequence); } @@ -163,7 +161,7 @@ public class PDALaunch extends Launch public synchronized boolean isInitialized() { return fInitialized; } - + /** * Returns whether the DSF services have been set to shut down. * @return @@ -171,7 +169,7 @@ public class PDALaunch extends Launch public synchronized boolean isShutDown() { return fShutDown; } - + @Override public boolean canTerminate() { return super.canTerminate() && isInitialized() && !isShutDown(); @@ -223,7 +221,7 @@ public class PDALaunch extends Launch rm.done(); } } - + @ConfinedToDsfExecutor("getSession().getExecutor()") private void doShutdown(final RequestMonitor rm) { fExecutor.execute( new PDAServicesShutdownSequence( @@ -242,13 +240,13 @@ public class PDALaunch extends Launch // session-ended event, finish step only after the dispatch. fExecutor.shutdown(); fireTerminate(); - + rm.setStatus(getStatus()); rm.done(); } }) ); } - + @SuppressWarnings("unchecked") @Override public Object getAdapter(Class adapter) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java.html new file mode 100644 index 00000000000..fb914a97cd8 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunch.java.html @@ -0,0 +1,271 @@ + + + +PDALaunch.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2008 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *******************************************************************************/
+ 11: package org.eclipse.dd.examples.pda.launch;
+
+ 13: import org.eclipse.core.runtime.IStatus;
+ 14: import org.eclipse.core.runtime.MultiStatus;
+ 15: import org.eclipse.core.runtime.Platform;
+ 16: import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
+ 17: import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor;
+ 18: import org.eclipse.dd.dsf.concurrent.ImmediateExecutor;
+ 19: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+ 20: import org.eclipse.dd.dsf.concurrent.Sequence;
+ 21: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
+ 22: import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
+ 23: import org.eclipse.dd.dsf.service.DsfSession;
+ 24: import org.eclipse.dd.examples.pda.PDAPlugin;
+ 25: import org.eclipse.dd.examples.pda.service.PDATerminatedEvent;
+ 26: import org.eclipse.debug.core.DebugException;
+ 27: import org.eclipse.debug.core.ILaunchConfiguration;
+ 28: import org.eclipse.debug.core.Launch;
+ 29: import org.eclipse.debug.core.model.ISourceLocator;
+ 30: import org.eclipse.debug.core.model.ITerminate;
+
+ 32: /**
+ 33:  * The PDA launch object. In general, a DSF-based debugger has to override 
+ 34:  * the base launch class in order to supply its own content providers for the 
+ 35:  * debug view.  Additionally, the PDA launch is used to monitor the state of the
+ 36:  * PDA debugger and to shutdown the DSF services and session belonging to the 
+ 37:  * launch.
+ 38:  * <p>
+ 39:  * The PDA launch class mostly contains methods and fields that can be accessed
+ 40:  * on any thread.  However, some fields and methods used for managing the DSF
+ 41:  * session need to be synchronized using the DSF executor.
+ 42:  * </p>
+ 43:  */
+ 44: @ThreadSafe
+ 45: public class PDALaunch extends Launch
+ 46: implements ITerminate
+ 47: {   
+ 48:     // DSF executor and session.  Both are created and shutdown by the launch. 
+ 49:     private final DefaultDsfExecutor fExecutor;
+ 50:     private final DsfSession fSession;
+
+ 52:     // Objects used to track the status of the DSF session.
+ 53:     private boolean fInitialized = false;
+ 54:     private boolean fShutDown = false;
+ 55:     
+ 56:     @ConfinedToDsfExecutor("getSession().getExecutor()")
+ 57:     private Sequence fInitializationSequence = null;
+
+ 59:     /**
+ 60:      * Launch constructor creates the launch for given parameters.  The
+ 61:      * constructor also creates a DSF session and an executor, so that 
+ 62:      * {@link #getSession()} returns a valid value, however no services 
+ 63:      * are initialized yet. 
+ 64:      * 
+ 65:      * @see Launch
+ 66:      */
+ 67:     public PDALaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) {
+ 68:         super(launchConfiguration, mode, locator);
+
+ 70:         // Create the dispatch queue to be used by debugger control and services 
+ 71:         // that belong to this launch
+ 72:         final DefaultDsfExecutor dsfExecutor = new DefaultDsfExecutor(PDAPlugin.ID_PDA_DEBUG_MODEL);
+ 73:         dsfExecutor.prestartCoreThread();
+ 74:         fExecutor = dsfExecutor;
+ 75:         fSession = DsfSession.startSession(fExecutor, PDAPlugin.ID_PDA_DEBUG_MODEL);
+ 76:     }
+
+ 78:     /**
+ 79:      * Returns the DSF services session that belongs to this launch.  This 
+ 80:      * method will always return a DsfSession object, however if the debugger 
+ 81:      * is shut down, the session will no longer active.
+ 82:      */
+ 83:     public DsfSession getSession() { return fSession; }
+
+ 85:     /**
+ 86:      * Initializes the DSF services using the specified parameters.  This 
+ 87:      * method has to be called on the executor thread in order to avoid 
+ 88:      * synchronization issues.  
+ 89:      */
+ 90:     @ConfinedToDsfExecutor("getSession().getExecutor()")
+ 91:     public void initializeServices(String program, int requestPort, int eventPort, final RequestMonitor rm)
+ 92:     {
+ 93:         // Double-check that we're being called in the correct thread.
+ 94:         assert fExecutor.isInExecutorThread();
+
+ 96:         // Check if shutdownServices() was called already, which would be 
+ 97:         // highly unusual, but if so we don't need to do anything except set 
+ 98:         // the initialized flag.
+ 99:         synchronized(this) {
+100:             if (fShutDown) {
+101:                 fInitialized = true;
+102:                 return;
+103:             }
+104:         }
+
+106:         // Register the launch as listener for services events.
+107:         fSession.addServiceEventListener(PDALaunch.this, null);
+
+109:         // The initialization sequence is stored in a field to allow it to be 
+110:         // canceled if shutdownServices() is called before the sequence 
+111:         // completes.
+112:         fInitializationSequence = new PDAServicesInitSequence(
+113:             getSession(), program, requestPort, eventPort, 
+114:             new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
+115:                 @Override
+116:                 protected void handleCompleted() {
+117:                     // Set the initialized flag and check whether the 
+118:                     // shutdown flag is set.  Access the flags in a 
+119:                     // synchronized section as these flags can be accessed
+120:                     // on any thread.
+121:                     boolean doShutdown = false;
+122:                     synchronized (this) { 
+123:                         fInitialized = true;
+124:                         fInitializationSequence = null;
+125:                         if (fShutDown) {
+126:                             doShutdown = true;
+127:                         }
+128:                     }
+
+130:                     if (doShutdown) {
+131:                         // If shutdownServices() was already called, start the 
+132:                         // shutdown sequence now.
+133:                         doShutdown(rm);
+134:                     } else {
+135:                         // If there was an error in the startup sequence, 
+136:                         // report the error to the client.
+137:                         if (getStatus().getSeverity() == IStatus.ERROR) {
+138:                             rm.setStatus(getStatus());
+139:                         }
+140:                         rm.done();
+141:                     }
+142:                     fireChanged();
+143:                 }
+144:             });
+
+146:         // Finally, execute the sequence. 
+147:         getSession().getExecutor().execute(fInitializationSequence);
+148:     }
+
+150:     /**
+151:      * Event handler for a debugger terminated event.    
+152:      */
+153:     @DsfServiceEventHandler 
+154:     public void eventDispatched(PDATerminatedEvent event) {
+155:         shutdownServices(new RequestMonitor(ImmediateExecutor.getInstance(), null));
+156:     }
+
+158:     /**
+159:      * Returns whether the DSF service initialization sequence has completed yet.
+160:      */
+161:     public synchronized boolean isInitialized() {
+162:         return fInitialized;
+163:     }
+
+165:     /**
+166:      * Returns whether the DSF services have been set to shut down.
+167:      * @return
+168:      */
+169:     public synchronized boolean isShutDown() {
+170:         return fShutDown;
+171:     }
+
+173:     @Override
+174:     public boolean canTerminate() {
+175:         return super.canTerminate() && isInitialized() && !isShutDown();
+176:     }
+
+178:     @Override
+179:     public boolean isTerminated() {
+180:         return super.isTerminated() || isShutDown();
+181:     }
+
+
+184:     @Override
+185:     public void terminate() throws DebugException {
+186:         if (isShutDown()) return;
+187:         super.terminate();
+188:     }
+
+190:     /**
+191:      * Shuts down the services, the session and the executor associated with 
+192:      * this launch.  
+193:      * <p>
+194:      * Note: The argument request monitor to this method should NOT use the
+195:      * executor that belongs to this launch.  By the time the shutdown is 
+196:      * complete, this executor will not be dispatching anymore and the 
+197:      * request monitor will never be invoked.  Instead callers should use
+198:      * the {@link ImmediateExecutor}.
+199:      * </p>
+200:      * @param rm The request monitor invoked when the shutdown is complete.    
+201:      */
+202:     @ConfinedToDsfExecutor("getSession().getExecutor()")
+203:     public void shutdownServices(final RequestMonitor rm) {
+204:         // Check initialize and shutdown flags to determine if the shutdown
+205:         // sequence can be called yet.
+206:         boolean doShutdown = false;
+207:         synchronized (this) {
+208:             if (!fInitialized && fInitializationSequence != null) {
+209:                 // Launch has not yet initialized, try to cancel the 
+210:                 // shutdown sequence.
+211:                 fInitializationSequence.cancel(false);
+212:             } else {
+213:                 doShutdown = !fShutDown && fInitialized;
+214:             }
+215:             fShutDown = true;
+216:         }
+
+218:         if (doShutdown) {
+219:             doShutdown(rm);
+220:         } else {
+221:             rm.done();
+222:         }
+223:     }
+
+225:     @ConfinedToDsfExecutor("getSession().getExecutor()")
+226:     private void doShutdown(final RequestMonitor rm) {
+227:         fExecutor.execute( new PDAServicesShutdownSequence(
+228:             fExecutor, fSession.getId(),
+229:             new RequestMonitor(fSession.getExecutor(), rm) { 
+230:                 @Override
+231:                 public void handleCompleted() {
+232:                     fSession.removeServiceEventListener(PDALaunch.this);
+233:                     if (!getStatus().isOK()) {
+234:                         PDAPlugin.getDefault().getLog().log(new MultiStatus(
+235:                             PDAPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$
+236:                     }
+237:                     // Last order of business, shutdown the dispatch queue.
+238:                     DsfSession.endSession(fSession);
+239:                     // endSession takes a full dispatch to distribute the 
+240:                     // session-ended event, finish step only after the dispatch.
+241:                     fExecutor.shutdown();
+242:                     fireTerminate();
+
+244:                     rm.setStatus(getStatus());
+245:                     rm.done();
+246:                 }
+247:             }) );
+248:     }
+
+250:     @SuppressWarnings("unchecked")
+251:     @Override
+252:     public Object getAdapter(Class adapter) {
+253:         // Force adapters to be loaded.  Otherwise the adapter manager may not find
+254:         // the model proxy adapter for DSF-based debug elements.
+255:         Platform.getAdapterManager().loadAdapter(this, adapter.getName());
+256:         return super.getAdapter(adapter);
+257:     }
+258: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java.html new file mode 100644 index 00000000000..f6c4b38f025 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java.html @@ -0,0 +1,234 @@ + + + +PDALaunchDelegate.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2005, 2008 IBM Corporation and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  *
+  8:  * Contributors:
+  9:  *     IBM Corporation - initial API and implementation
+ 10:  *     Bjorn Freeman-Benson - initial API and implementation
+ 11:  *     Wind River Systems - adopted to use with DSF
+ 12:  *******************************************************************************/
+ 13: package org.eclipse.dd.examples.pda.launch;
+
+ 15: import java.io.File;
+ 16: import java.io.IOException;
+ 17: import java.net.ServerSocket;
+ 18: import java.text.MessageFormat;
+ 19: import java.util.ArrayList;
+ 20: import java.util.List;
+ 21: import java.util.concurrent.ExecutionException;
+
+ 23: import org.eclipse.core.resources.IFile;
+ 24: import org.eclipse.core.resources.ResourcesPlugin;
+ 25: import org.eclipse.core.runtime.CoreException;
+ 26: import org.eclipse.core.runtime.IProgressMonitor;
+ 27: import org.eclipse.core.runtime.IStatus;
+ 28: import org.eclipse.core.runtime.Path;
+ 29: import org.eclipse.core.runtime.Status;
+ 30: import org.eclipse.core.variables.IValueVariable;
+ 31: import org.eclipse.core.variables.VariablesPlugin;
+ 32: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+ 33: import org.eclipse.dd.dsf.concurrent.Query;
+ 34: import org.eclipse.dd.examples.pda.PDAPlugin;
+ 35: import org.eclipse.debug.core.DebugException;
+ 36: import org.eclipse.debug.core.DebugPlugin;
+ 37: import org.eclipse.debug.core.ILaunch;
+ 38: import org.eclipse.debug.core.ILaunchConfiguration;
+ 39: import org.eclipse.debug.core.model.IPersistableSourceLocator;
+ 40: import org.eclipse.debug.core.model.ISourceLocator;
+ 41: import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
+ 42: import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2;
+
+
+ 45: /**
+ 46:  * Launches PDA program on a PDA interpretter written in Perl 
+ 47:  */
+ 48: public class PDALaunchDelegate extends LaunchConfigurationDelegate {
+
+ 50:     @Override
+ 51:     public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
+ 52:         // Need to configure the source locator before creating the launch
+ 53:         // because once the launch is created and added to launch manager, 
+ 54:         // the adapters will be created for the whole session, including 
+ 55:         // the source lookup adapter.
+ 56:         ISourceLocator locator = getSourceLocator(configuration);
+
+ 58:         return new PDALaunch(configuration, mode, locator);
+ 59:     }
+
+ 61:     @Override
+ 62:     public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
+ 63:         // PDA programs do not require building.
+ 64:         return false;
+ 65:     }
+
+ 67:     /**
+ 68:      * Returns a source locator created based on the attributes in the launch configuration.
+ 69:      */
+ 70:     private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException {
+ 71:         String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null);
+ 72:         if (type == null) {
+ 73:             type = configuration.getType().getSourceLocatorId();
+ 74:         }
+ 75:         if (type != null) {
+ 76:             IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type);
+ 77:             String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null);
+ 78:             if (memento == null) {
+ 79:                 locator.initializeDefaults(configuration);
+ 80:             } else {
+ 81:                 if(locator instanceof IPersistableSourceLocator2)
+ 82:                     ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration);
+ 83:                 else
+ 84:                     locator.initializeFromMemento(memento);
+ 85:             }
+ 86:             return locator;
+ 87:         }
+ 88:         return null;
+ 89:     }
+
+ 91:     public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
+ 92:         String program = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null);
+ 93:         if (program == null) {
+ 94:             abort("Perl program unspecified.", null);
+ 95:         }
+
+ 97:         int requestPort = findFreePort();
+ 98:         int eventPort = findFreePort();
+ 99:         if (requestPort == -1 || eventPort == -1) {
+100:             abort("Unable to find free port", null);
+101:         }
+
+103:         launchProcess(launch, program, requestPort, eventPort);
+104:         PDALaunch pdaLaunch = (PDALaunch)launch; 
+105:         initServices(pdaLaunch, program, requestPort, eventPort);
+106:     }
+
+108:     /**
+109:      * Launches PDA interpreter with the given program.
+110:      *  
+111:      * @param launch Launch that will contain the new process.
+112:      * @param program PDA program to use in the interpreter.
+113:      * @param requestPort The port number for connecting the request socket.
+114:      * @param eventPort The port number for connecting the events socket.
+115:      * 
+116:      * @throws CoreException 
+117:      */
+118:     private void launchProcess(ILaunch launch, String program, int requestPort, int eventPort) throws CoreException {
+119:         List<String> commandList = new ArrayList<String>();
+
+121:         // Find Perl executable
+122:         IValueVariable perl = VariablesPlugin.getDefault().getStringVariableManager().getValueVariable(PDAPlugin.VARIALBE_PERL_EXECUTABLE);
+123:         if (perl == null) {
+124:             abort("Perl executable location undefined. Check value of ${dsfPerlExecutable}.", null);
+125:         }
+126:         String path = perl.getValue();
+127:         if (path == null) {
+128:             abort("Perl executable location unspecified. Check value of ${dsfPerlExecutable}.", null);
+129:         }
+130:         File exe = new File(path);
+131:         if (!exe.exists()) {
+132:             abort(MessageFormat.format("Specified Perl executable {0} does not exist. Check value of $dsfPerlExecutable.", new Object[]{path}), null);
+133:         }
+134:         commandList.add(path);
+
+136:         // Add PDA VM
+137:         File vm = PDAPlugin.getFileInPlugin(new Path("pdavm/pda.pl"));
+138:         if (vm == null) {
+139:             abort("Missing PDA VM", null);
+140:         }
+141:         commandList.add(vm.getAbsolutePath());
+
+143:         // Add PDA program
+144:         IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(program));
+145:         if (!file.exists()) {
+146:             abort(MessageFormat.format("Perl program {0} does not exist.", new Object[] {file.getFullPath().toString()}), null);
+147:         }
+
+149:         commandList.add(file.getLocation().toOSString());
+
+151:         // Add debug arguments - i.e. '-debug requestPort eventPort'
+152:         commandList.add("-debug");
+153:         commandList.add("" + requestPort);
+154:         commandList.add("" + eventPort);
+
+156:         // Launch the perl process.
+157:         String[] commandLine = commandList.toArray(new String[commandList.size()]);
+158:         Process process = DebugPlugin.exec(commandLine, null);
+
+160:         // Create a debug platform process object and add it to the launch.
+161:         DebugPlugin.newProcess(launch, process, path);
+162:     }
+
+164:     /**
+165:      * Calls the launch to initialize DSF services for this launch.
+166:      */
+167:     private void initServices(final PDALaunch pdaLaunch, final String program, final int requestPort, final int eventPort) 
+168:     throws CoreException 
+169:     {
+170:         // Synchronization object to use when waiting for the services initialization.
+171:         Query<Object> initQuery = new Query<Object>() {
+172:             @Override
+173:             protected void execute(DataRequestMonitor<Object> rm) {
+174:                 pdaLaunch.initializeServices(program, requestPort, eventPort, rm);
+175:             }
+176:         };
+
+178:         // Submit the query to the executor.
+179:         pdaLaunch.getSession().getExecutor().execute(initQuery);
+180:         try {
+181:             // Block waiting for query results.
+182:             initQuery.get();
+183:         } catch (InterruptedException e1) {
+184:             throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$
+185:         } catch (ExecutionException e1) {
+186:             throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$
+187:         }
+188:     }
+
+190:     /**
+191:      * Throws an exception with a new status containing the given
+192:      * message and optional exception.
+193:      * 
+194:      * @param message error message
+195:      * @param e underlying exception
+196:      * @throws CoreException
+197:      */
+198:     private void abort(String message, Throwable e) throws CoreException {
+199:         throw new CoreException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, 0, message, e));
+200:     }
+
+202:     /**
+203:      * Returns a free port number on localhost, or -1 if unable to find a free port.
+204:      */
+205:     public static int findFreePort() {
+206:         ServerSocket socket= null;
+207:         try {
+208:             socket= new ServerSocket(0);
+209:             return socket.getLocalPort();
+210:         } catch (IOException e) { 
+211:         } finally {
+212:             if (socket != null) {
+213:                 try {
+214:                     socket.close();
+215:                 } catch (IOException e) {
+216:                 }
+217:             }
+218:         }
+219:         return -1;                
+220:     }                
+221: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java index a92a61fc79d..781e8c505e3 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java @@ -44,12 +44,6 @@ public class PDAServicesInitSequence extends Sequence { fCommandControl = new PDACommandControl(fSession, fProgram, fRequestPort, fEventPort); fCommandControl.initialize(requestMonitor); } - - @Override - public void rollBack(RequestMonitor rm) { - // TODO Auto-generated method stub - super.rollBack(rm); - } }, new Step() { @Override @@ -77,7 +71,7 @@ public class PDAServicesInitSequence extends Sequence { @Override public void execute(final RequestMonitor requestMonitor) { // Create the breakpoint mediator and start tracking PDA breakpoints. - + final BreakpointsMediator bpmService = new BreakpointsMediator( fSession, new PDABreakpointAttributeTranslator()); bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) { @@ -88,19 +82,22 @@ public class PDAServicesInitSequence extends Sequence { }); } }, - new Step() { @Override + new Step() { + @Override public void execute(RequestMonitor requestMonitor) { // Start the stack service. new PDAStack(fSession).initialize(requestMonitor); } }, - new Step() { @Override + new Step() { + @Override public void execute(RequestMonitor requestMonitor) { // Start the service to track expressions. new PDAExpressions(fSession).initialize(requestMonitor); } }, - new Step() { @Override + new Step() { + @Override public void execute(RequestMonitor requestMonitor) { fRunControl.resume(fCommandControl.getProgramDMContext(), requestMonitor); } @@ -125,7 +122,7 @@ public class PDAServicesInitSequence extends Sequence { fRequestPort = requestPort; fEventPort = eventPort; } - + @Override public Step[] getSteps() { return fSteps; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java.html new file mode 100644 index 00000000000..7f4aae65d3d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java.html @@ -0,0 +1,140 @@ + + + +PDAServicesInitSequence.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2008 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *******************************************************************************/
+ 11: package org.eclipse.dd.examples.pda.launch;
+
+ 13: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+ 14: import org.eclipse.dd.dsf.concurrent.Sequence;
+ 15: import org.eclipse.dd.dsf.debug.service.BreakpointsMediator;
+ 16: import org.eclipse.dd.dsf.debug.service.StepQueueManager;
+ 17: import org.eclipse.dd.dsf.service.DsfSession;
+ 18: import org.eclipse.dd.examples.pda.service.PDABreakpointAttributeTranslator;
+ 19: import org.eclipse.dd.examples.pda.service.PDABreakpoints;
+ 20: import org.eclipse.dd.examples.pda.service.PDACommandControl;
+ 21: import org.eclipse.dd.examples.pda.service.PDAExpressions;
+ 22: import org.eclipse.dd.examples.pda.service.PDARunControl;
+ 23: import org.eclipse.dd.examples.pda.service.PDAStack;
+
+ 25: /**
+ 26:  * The initialization sequence for PDA debugger services.  This sequence contains
+ 27:  * the series of steps that are executed to properly initialize the PDA-DSF debug
+ 28:  * session.  If any of the individual steps fail, the initialization will abort.   
+ 29:  * <p>
+ 30:  * The order in which services are initialized is important.  Some services depend
+ 31:  * on other services and they assume that they will be initialized only if those
+ 32:  * services are active.  Also the service events are prioritized and their priority
+ 33:  * depends on the order in which the services were initialized.
+ 34:  * </p>
+ 35:  */
+ 36: public class PDAServicesInitSequence extends Sequence {
+
+ 38:     Step[] fSteps = new Step[] {
+ 39:         new Step() 
+ 40:         { 
+ 41:             @Override
+ 42:             public void execute(RequestMonitor requestMonitor) {
+ 43:                 // Create the connection to PDA debugger.
+ 44:                 fCommandControl = new PDACommandControl(fSession, fProgram, fRequestPort, fEventPort);
+ 45:                 fCommandControl.initialize(requestMonitor);
+ 46:             }
+ 47:         },
+ 48:         new Step() { 
+ 49:             @Override
+ 50:             public void execute(RequestMonitor requestMonitor) {
+ 51:                 // Start the run control service.
+ 52:                 fRunControl = new PDARunControl(fSession);
+ 53:                 fRunControl.initialize(requestMonitor);
+ 54:             }
+ 55:         },
+ 56:         new Step() { 
+ 57:             @Override
+ 58:             public void execute(RequestMonitor requestMonitor) {
+ 59:                 // Start the service to manage step actions.
+ 60:                 new StepQueueManager(fSession).initialize(requestMonitor);
+ 61:             }
+ 62:         },
+ 63:         new Step() { 
+ 64:             @Override
+ 65:             public void execute(final RequestMonitor requestMonitor) {
+ 66:                 // Start the low-level breakpoint service 
+ 67:                 new PDABreakpoints(fSession).initialize(new RequestMonitor(getExecutor(), requestMonitor));
+ 68:             }
+ 69:         },
+ 70:         new Step() { 
+ 71:             @Override
+ 72:             public void execute(final RequestMonitor requestMonitor) {
+ 73:                 // Create the breakpoint mediator and start tracking PDA breakpoints.
+
+ 75:                 final BreakpointsMediator bpmService = new BreakpointsMediator(
+ 76:                     fSession, new PDABreakpointAttributeTranslator());
+ 77:                 bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) {
+ 78:                     @Override
+ 79:                     protected void handleOK() {
+ 80:                         bpmService.startTrackingBreakpoints(fCommandControl.getProgramDMContext(), requestMonitor);
+ 81:                     }
+ 82:                 }); 
+ 83:             }
+ 84:         },
+ 85:         new Step() { @Override
+ 86:             public void execute(RequestMonitor requestMonitor) {
+ 87:             // Start the stack service.
+ 88:             new PDAStack(fSession).initialize(requestMonitor);
+ 89:         }
+ 90:         },
+ 91:         new Step() { @Override
+ 92:             public void execute(RequestMonitor requestMonitor) {
+ 93:             // Start the service to track expressions.
+ 94:             new PDAExpressions(fSession).initialize(requestMonitor);
+ 95:         }
+ 96:         },
+ 97:         new Step() { @Override
+ 98:             public void execute(RequestMonitor requestMonitor) {
+ 99:             fRunControl.resume(fCommandControl.getProgramDMContext(), requestMonitor);
+100:         }
+101:         },
+102:     };
+
+104:     // Sequence input parameters, used in initializing services.
+105:     private DsfSession fSession;
+106:     private String fProgram;
+107:     private int fRequestPort;
+108:     private int fEventPort;
+
+110:     // Service references, initialized when created and used in initializing other services.
+111:     private PDACommandControl fCommandControl;
+112:     private PDARunControl fRunControl;
+
+114:     public PDAServicesInitSequence(DsfSession session, String program, int requestPort, int eventPort, RequestMonitor rm) 
+115:     {
+116:         super(session.getExecutor(), rm);
+117:         fSession = session;
+118:         fProgram = program;
+119:         fRequestPort = requestPort;
+120:         fEventPort = eventPort;
+121:     }
+
+123:     @Override
+124:     public Step[] getSteps() {
+125:         return fSteps;
+126:     }
+127: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java index ccdf9aef3ca..c8dc52927c6 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java @@ -63,7 +63,7 @@ public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTra } public List> getBreakpointAttributes(IBreakpoint bp, boolean bpManagerEnabled) - throws CoreException + throws CoreException { Map attrs = new HashMap(); @@ -82,15 +82,15 @@ public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTra // Copy breakpoint attributes. if (bp instanceof PDAWatchpoint) { attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_WATCHPOINT); - + copyAttributes(platformBpAttrs, attrs, fgPDAWatchpointAttributes); } else if (bp instanceof PDALineBreakpoint) { attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_LINE_BREAKPOINT); attrs.put(PDABreakpoints.ATTR_PROGRAM_PATH, marker.getResource().getFullPath().toString()); - + copyAttributes(platformBpAttrs, attrs, fgPDALineBreakpointAttributes); } - + // If the breakpoint manager is disabled, override the enabled attribute. if (!bpManagerEnabled) { attrs.put(IBreakpoint.ENABLED, false); @@ -111,7 +111,7 @@ public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTra } } } - + public boolean canUpdateAttributes(IBreakpointDMContext bp, Map delta) { // PDA debugger only allows updating of the action property of the watchpoint. // All other breakpoint updates will require a re-installation. diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java.html new file mode 100644 index 00000000000..7696dc71e9e --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpointAttributeTranslator.java.html @@ -0,0 +1,148 @@ + + + +PDABreakpointAttributeTranslator.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2008 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *******************************************************************************/
+ 11: package org.eclipse.dd.examples.pda.service;
+
+ 13: import java.util.ArrayList;
+ 14: import java.util.HashMap;
+ 15: import java.util.List;
+ 16: import java.util.Map;
+
+ 18: import org.eclipse.core.resources.IMarker;
+ 19: import org.eclipse.core.runtime.CoreException;
+ 20: import org.eclipse.core.runtime.IStatus;
+ 21: import org.eclipse.core.runtime.Status;
+ 22: import org.eclipse.dd.dsf.debug.service.BreakpointsMediator;
+ 23: import org.eclipse.dd.dsf.debug.service.IBreakpointAttributeTranslator;
+ 24: import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointDMContext;
+ 25: import org.eclipse.dd.examples.pda.PDAPlugin;
+ 26: import org.eclipse.dd.examples.pda.breakpoints.PDALineBreakpoint;
+ 27: import org.eclipse.dd.examples.pda.breakpoints.PDAWatchpoint;
+ 28: import org.eclipse.debug.core.DebugException;
+ 29: import org.eclipse.debug.core.model.IBreakpoint;
+
+ 31: /**
+ 32:  * Translator between {@link PDALineBreakpoint} object attributes and 
+ 33:  * attributes used by the {@link PDABreakpoints} service.  
+ 34:  * <p>
+ 35:  * The attribute translator is used by the standard {@link BreakpointsMediator} 
+ 36:  * service to map between platform breakpoint attributes and target-side DSF
+ 37:  * breakpoint attributes.  Thus, this object encapsulates the model-specific
+ 38:  * functionality of synchronizing target side and IDE-side breakpoint objects.  
+ 39:  * </p>
+ 40:  */
+ 41: public class PDABreakpointAttributeTranslator implements IBreakpointAttributeTranslator {
+
+ 43:     // Arrays of common attributes between the two breakpoint types.  These 
+ 44:     // attributes can be copied directly without translation.
+ 45:     private static final String[] fgPDALineBreakpointAttributes = {
+ 46:         IBreakpoint.ENABLED,
+ 47:         IMarker.LINE_NUMBER,
+ 48:     };
+ 49:     private static final String[] fgPDAWatchpointAttributes = {
+ 50:         IBreakpoint.ENABLED,
+ 51:         PDAWatchpoint.FUNCTION_NAME,
+ 52:         PDAWatchpoint.VAR_NAME,
+ 53:         PDAWatchpoint.ACCESS,
+ 54:         PDAWatchpoint.MODIFICATION
+ 55:     };
+
+ 57:     // PDA breakpoints translator doesn't keep any state and it doesn't 
+ 58:     // need to initialize or clean up.
+ 59:     public void initialize(BreakpointsMediator mediator) {
+ 60:     }
+
+ 62:     public void dispose() {
+ 63:     }
+
+ 65:     public List<Map<String, Object>> getBreakpointAttributes(IBreakpoint bp, boolean bpManagerEnabled) 
+ 66:     throws CoreException 
+ 67:     {
+ 68:         Map<String, Object> attrs = new HashMap<String, Object>(); 
+
+ 70:         // Check that the marker exists and retrieve its attributes.  
+ 71:         // Due to accepted race conditions, the breakpiont marker may become null 
+ 72:         // while this method is being invoked.  In this case throw an exception
+ 73:         // and let the caller handle it.
+ 74:         IMarker marker = bp.getMarker();
+ 75:         if (marker == null || !marker.exists()) {
+ 76:             throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Breakpoint marker does not exist", null)); 
+ 77:         }
+ 78:         // Suppress cast warning: platform is still on Java 1.3
+ 79:         @SuppressWarnings("unchecked")
+ 80:         Map<String, Object> platformBpAttrs = marker.getAttributes();
+
+ 82:         // Copy breakpoint attributes.
+ 83:         if (bp instanceof PDAWatchpoint) {
+ 84:             attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_WATCHPOINT);
+
+ 86:             copyAttributes(platformBpAttrs, attrs, fgPDAWatchpointAttributes);
+ 87:         } else if (bp instanceof PDALineBreakpoint) {
+ 88:             attrs.put(PDABreakpoints.ATTR_BREAKPOINT_TYPE, PDABreakpoints.PDA_LINE_BREAKPOINT);
+ 89:             attrs.put(PDABreakpoints.ATTR_PROGRAM_PATH, marker.getResource().getFullPath().toString()); 
+
+ 91:             copyAttributes(platformBpAttrs, attrs, fgPDALineBreakpointAttributes);
+ 92:         }
+
+ 94:         // If the breakpoint manager is disabled, override the enabled attribute.
+ 95:         if (!bpManagerEnabled) {
+ 96:             attrs.put(IBreakpoint.ENABLED, false);
+ 97:         }
+
+ 99:         // The breakpoint mediator allows for multiple target-side breakpoints 
+100:         // to be created for each IDE breakpoint.  Although in case of PDA this 
+101:         // feature is never used, we still have to return a list of attributes.
+102:         List<Map<String, Object>> retVal = new ArrayList<Map<String, Object>>(1);
+103:         retVal.add(attrs);
+104:         return retVal;
+105:     }
+
+107:     private void copyAttributes(Map<String, Object> srcMap, Map<String, Object> destMap, String[] attrs) {
+108:         for (String attr : attrs) {
+109:             if (srcMap.containsKey(attr)) {
+110:                 destMap.put(attr, srcMap.get(attr));
+111:             }
+112:         }
+113:     }
+
+115:     public boolean canUpdateAttributes(IBreakpointDMContext bp, Map<String, Object> delta) {
+116:         // PDA debugger only allows updating of the action property of the watchpoint.
+117:         // All other breakpoint updates will require a re-installation.
+118:         if (bp instanceof PDAWatchpoint) {
+119:             Map<String, Object> deltaCopy = new HashMap<String, Object>(delta);
+120:             deltaCopy.remove(PDAWatchpoint.ACCESS);
+121:             deltaCopy.remove(PDAWatchpoint.MODIFICATION);
+122:             return !deltaCopy.isEmpty();
+123:         }
+124:         return false;
+125:     }
+
+127:     public boolean supportsBreakpoint(IBreakpoint bp) {
+128:         return bp.getModelIdentifier().equals(PDAPlugin.ID_PDA_DEBUG_MODEL);
+129:     }
+
+131:     public void updateBreakpointStatus(IBreakpoint bp) {
+132:         // PDA breakpoints do not support status reporting
+133:     }
+
+135: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java index b0a4aa77e41..adfa26047b1 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java @@ -60,7 +60,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints public boolean equals(Object obj) { return baseEquals(obj) && (fLine.equals(((BreakpointDMContext) obj).fLine)); } - + @Override public int hashCode() { return baseHashCode() + fLine.hashCode(); @@ -71,7 +71,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints return baseToString() + ".breakpoint(" + fLine + ")"; //$NON-NLS-1$//$NON-NLS-2$*/ } } - + /** * Context representing a watch point. In PDA debugger, a watchpoint is * uniquely identified using the function and variable. @@ -97,7 +97,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints } return false; } - + @Override public int hashCode() { return baseHashCode() + fFunction.hashCode() + fVariable.hashCode(); @@ -108,119 +108,119 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints return baseToString() + ".watchpoint(" + fFunction + "::" + fVariable + ")"; } } - + // Attribute names public static final String ATTR_BREAKPOINT_TYPE = PDAPlugin.PLUGIN_ID + ".pdaBreakpointType"; //$NON-NLS-1$ public static final String PDA_LINE_BREAKPOINT = "breakpoint"; //$NON-NLS-1$ public static final String PDA_WATCHPOINT = "watchpoint"; //$NON-NLS-1$ public static final String ATTR_PROGRAM_PATH = PDAPlugin.PLUGIN_ID + ".pdaProgramPath"; //$NON-NLS-1$ - + // Services private PDACommandControl fCommandControl; // Breakpoints currently installed private Set fBreakpoints = new HashSet(); - /** - * The service constructor - * - * @param session The debugging session this service belongs to. - */ - public PDABreakpoints(DsfSession session) { - super(session); - } + /** + * The service constructor + * + * @param session The debugging session this service belongs to. + */ + public PDABreakpoints(DsfSession session) { + super(session); + } - @Override - public void initialize(final RequestMonitor rm) { - super.initialize(new RequestMonitor(getExecutor(), rm) { - @Override - protected void handleOK() { - doInitialize(rm); - } - }); - } + @Override + public void initialize(final RequestMonitor rm) { + super.initialize(new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleOK() { + doInitialize(rm); + } + }); + } - private void doInitialize(final RequestMonitor rm) { - // Get the services references - fCommandControl = getServicesTracker().getService(PDACommandControl.class); + private void doInitialize(final RequestMonitor rm) { + // Get the services references + fCommandControl = getServicesTracker().getService(PDACommandControl.class); - // Register this service - register(new String[] { IBreakpoints.class.getName(), PDABreakpoints.class.getName() }, - new Hashtable()); + // Register this service + register(new String[] { IBreakpoints.class.getName(), PDABreakpoints.class.getName() }, + new Hashtable()); - rm.done(); - } + rm.done(); + } - @Override - public void shutdown(final RequestMonitor rm) { - unregister(); - rm.done(); - } + @Override + public void shutdown(final RequestMonitor rm) { + unregister(); + rm.done(); + } - @Override - protected BundleContext getBundleContext() { - return PDAPlugin.getBundleContext(); - } + @Override + protected BundleContext getBundleContext() { + return PDAPlugin.getBundleContext(); + } - public void getBreakpoints(final IBreakpointsTargetDMContext context, final DataRequestMonitor rm) { - // Validate the context - if (!fCommandControl.getProgramDMContext().equals(context)) { - PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoints target context"); - return; - } - - rm.setData(fBreakpoints.toArray(new IBreakpointDMContext[fBreakpoints.size()])); - rm.done(); - } - - public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor rm) { - PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Retrieving breakpoint data is not supported"); - } - - public void insertBreakpoint(IBreakpointsTargetDMContext context, Map attributes, - DataRequestMonitor rm) - { - Boolean enabled = (Boolean)attributes.get(IBreakpoint.ENABLED); - if (enabled != null && !enabled.booleanValue()) { - // If the breakpoint is disabled, just fail the request. - PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint is disabled"); - } else { - String type = (String) attributes.get(ATTR_BREAKPOINT_TYPE); - - if (PDA_LINE_BREAKPOINT.equals(type)) { - // Retrieve the PDA program context from the context given in the - // argument. This service is typically only called by the - // breakpoints mediator, which was called with the program context - // in the services initialization sequence. So checking if - // programCtx != null is mostly a formality. - PDAProgramDMContext programCtx = DMContexts.getAncestorOfType(context, PDAProgramDMContext.class); - if (programCtx != null) { - doInsertBreakpoint(programCtx, attributes, rm); - } else { - PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown breakpoint type"); - } - } - else if (PDA_WATCHPOINT.equals(type)) { - doInsertWatchpoint(attributes, rm); - } - else { - PDAPlugin.failRequest(rm, REQUEST_FAILED, "Unknown breakpoint type"); - } - } - } - - private void doInsertBreakpoint(PDAProgramDMContext programCtx, final Map attributes, final DataRequestMonitor rm) - { - // Compare the program path in the breakpoint with the path in the PDA - // program context. Only insert the breakpoint if the program matches. - String program = (String)attributes.get(ATTR_PROGRAM_PATH); - if (!programCtx.getProgram().equals(program)) { - PDAPlugin.failRequest(rm, REQUEST_FAILED, "Invalid file name"); + public void getBreakpoints(final IBreakpointsTargetDMContext context, final DataRequestMonitor rm) { + // Validate the context + if (!fCommandControl.getProgramDMContext().equals(context)) { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoints target context"); return; - } - - // Retrieve the line. - Integer line = (Integer)attributes.get(IMarker.LINE_NUMBER); + } + + rm.setData(fBreakpoints.toArray(new IBreakpointDMContext[fBreakpoints.size()])); + rm.done(); + } + + public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor rm) { + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Retrieving breakpoint data is not supported"); + } + + public void insertBreakpoint(IBreakpointsTargetDMContext context, Map attributes, + DataRequestMonitor rm) + { + Boolean enabled = (Boolean)attributes.get(IBreakpoint.ENABLED); + if (enabled != null && !enabled.booleanValue()) { + // If the breakpoint is disabled, just fail the request. + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint is disabled"); + } else { + String type = (String) attributes.get(ATTR_BREAKPOINT_TYPE); + + if (PDA_LINE_BREAKPOINT.equals(type)) { + // Retrieve the PDA program context from the context given in the + // argument. This service is typically only called by the + // breakpoints mediator, which was called with the program context + // in the services initialization sequence. So checking if + // programCtx != null is mostly a formality. + PDAProgramDMContext programCtx = DMContexts.getAncestorOfType(context, PDAProgramDMContext.class); + if (programCtx != null) { + doInsertBreakpoint(programCtx, attributes, rm); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown breakpoint type"); + } + } + else if (PDA_WATCHPOINT.equals(type)) { + doInsertWatchpoint(attributes, rm); + } + else { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Unknown breakpoint type"); + } + } + } + + private void doInsertBreakpoint(PDAProgramDMContext programCtx, final Map attributes, final DataRequestMonitor rm) + { + // Compare the program path in the breakpoint with the path in the PDA + // program context. Only insert the breakpoint if the program matches. + String program = (String)attributes.get(ATTR_PROGRAM_PATH); + if (!programCtx.getProgram().equals(program)) { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Invalid file name"); + return; + } + + // Retrieve the line. + Integer line = (Integer)attributes.get(IMarker.LINE_NUMBER); if (line == null) { PDAPlugin.failRequest(rm, REQUEST_FAILED, "No breakpoint line specified"); return; @@ -235,7 +235,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already set"); return; } - + // Add the new breakpoint context to the list of known breakpoints. // Adding it here, before the set command is completed will prevent // a possibility of a second breakpoint being installed in the same @@ -251,7 +251,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints rm.setData(breakpointCtx); rm.done(); } - + @Override protected void handleErrorOrCancel() { // If inserting of the breakpoint failed, remove it from @@ -260,10 +260,10 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints super.handleErrorOrCancel(); } }); - } + } - private void doInsertWatchpoint(final Map attributes, final DataRequestMonitor rm) - { + private void doInsertWatchpoint(final Map attributes, final DataRequestMonitor rm) + { String function = (String)attributes.get(PDAWatchpoint.FUNCTION_NAME); if (function == null) { PDAPlugin.failRequest(rm, REQUEST_FAILED, "No function specified"); @@ -291,7 +291,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints PDAPlugin.failRequest(rm, REQUEST_FAILED, "Watchpoint already set"); return; } - + // Determine the watch operation to perform. PDAWatchCommand.WatchOperation watchOperation = PDAWatchCommand.WatchOperation.NONE; if (isAccess && isModification) { @@ -317,7 +317,7 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints rm.setData(watchpointCtx); rm.done(); } - + @Override protected void handleErrorOrCancel() { // Since the command failed, we need to remove the breakpoint from @@ -326,29 +326,29 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints super.handleErrorOrCancel(); } }); - } + } - public void removeBreakpoint(IBreakpointDMContext bpCtx, RequestMonitor rm) { - if (!fBreakpoints.contains(bpCtx)) { + public void removeBreakpoint(IBreakpointDMContext bpCtx, RequestMonitor rm) { + if (!fBreakpoints.contains(bpCtx)) { PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already removed"); return; - } - + } + if (bpCtx instanceof BreakpointDMContext) { - doRemoveBreakpoint((BreakpointDMContext)bpCtx, rm); - } else if (bpCtx instanceof WatchpointDMContext) { + doRemoveBreakpoint((BreakpointDMContext)bpCtx, rm); + } else if (bpCtx instanceof WatchpointDMContext) { doRemoveWatchpoint((WatchpointDMContext)bpCtx, rm); - } else { - PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint"); - } - } + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint"); + } + } private void doRemoveBreakpoint(BreakpointDMContext bpCtx, RequestMonitor rm) { // Remove the breakpoint from the table right away, so that even when // the remove is being processed, a new breakpoint can be created at the same // location. fBreakpoints.remove(bpCtx); - + fCommandControl.queueCommand( new PDAClearBreakpointCommand(fCommandControl.getProgramDMContext(), bpCtx.fLine), new DataRequestMonitor(getExecutor(), rm)); @@ -356,23 +356,31 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints private void doRemoveWatchpoint(WatchpointDMContext bpCtx, RequestMonitor rm) { fBreakpoints.remove(bpCtx); - + // Watchpoints are cleared using the same command, but with a "no watch" operation fCommandControl.queueCommand( new PDAWatchCommand( fCommandControl.getProgramDMContext(), bpCtx.fFunction, bpCtx.fVariable, PDAWatchCommand.WatchOperation.NONE), - new DataRequestMonitor(getExecutor(), rm)); + new DataRequestMonitor(getExecutor(), rm)); } - public void updateBreakpoint(final IBreakpointDMContext bpCtx, Map attributes, final RequestMonitor rm) { + public void updateBreakpoint(final IBreakpointDMContext bpCtx, Map attributes, final RequestMonitor rm) { if (!fBreakpoints.contains(bpCtx)) { PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint not installed"); return; } - + if (bpCtx instanceof BreakpointDMContext) { PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Modifying PDA breakpoints is not supported"); } else if (bpCtx instanceof WatchpointDMContext) { + WatchpointDMContext wpCtx = (WatchpointDMContext)bpCtx; + if (!wpCtx.fFunction.equals(attributes.get(PDAWatchpoint.FUNCTION_NAME)) || + !wpCtx.fVariable.equals(attributes.get(PDAWatchpoint.VAR_NAME)) ) + { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Cannot modify watchpoint function or variable"); + return; + } + // PDA debugger can only track one watchpoint in the same location, // so we can simply remove the existing context from the set and // call insert again. @@ -391,5 +399,5 @@ public class PDABreakpoints extends AbstractDsfService implements IBreakpoints } else { PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint"); } - } + } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java.html new file mode 100644 index 00000000000..5976bfa268d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDABreakpoints.java.html @@ -0,0 +1,416 @@ + + + +PDABreakpoints.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2007 Ericsson and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  *
+  8:  * Contributors:
+  9:  *     Ericsson - Initial API and implementation
+ 10:  *******************************************************************************/
+
+ 12: package org.eclipse.dd.examples.pda.service;
+
+ 14: import java.util.HashSet;
+ 15: import java.util.Hashtable;
+ 16: import java.util.Map;
+ 17: import java.util.Set;
+
+ 19: import org.eclipse.core.resources.IMarker;
+ 20: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+ 21: import org.eclipse.dd.dsf.concurrent.Immutable;
+ 22: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+ 23: import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
+ 24: import org.eclipse.dd.dsf.datamodel.DMContexts;
+ 25: import org.eclipse.dd.dsf.datamodel.IDMContext;
+ 26: import org.eclipse.dd.dsf.debug.service.IBreakpoints;
+ 27: import org.eclipse.dd.dsf.service.AbstractDsfService;
+ 28: import org.eclipse.dd.dsf.service.DsfSession;
+ 29: import org.eclipse.dd.examples.pda.PDAPlugin;
+ 30: import org.eclipse.dd.examples.pda.breakpoints.PDAWatchpoint;
+ 31: import org.eclipse.dd.examples.pda.service.commands.PDAClearBreakpointCommand;
+ 32: import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
+ 33: import org.eclipse.dd.examples.pda.service.commands.PDASetBreakpointCommand;
+ 34: import org.eclipse.dd.examples.pda.service.commands.PDAWatchCommand;
+ 35: import org.eclipse.debug.core.model.IBreakpoint;
+ 36: import org.osgi.framework.BundleContext;
+
+ 38: /**
+ 39:  * Initial breakpoint service implementation.
+ 40:  * Implements the IBreakpoints interface.
+ 41:  */
+ 42: public class PDABreakpoints extends AbstractDsfService implements IBreakpoints
+ 43: {
+ 44:     /**
+ 45:      * Context representing a PDA line breakpoint.  In PDA debugger, since there is only 
+ 46:      * one file being debugged at a time, a breakpoint is uniquely identified using the 
+ 47:      * line number only.
+ 48:      */
+ 49:     @Immutable
+ 50:     private static class BreakpointDMContext extends AbstractDMContext implements IBreakpointDMContext {
+
+ 52:         final Integer fLine;
+
+ 54:         public BreakpointDMContext(String sessionId, PDAProgramDMContext commandControlCtx, Integer line) {
+ 55:             super(sessionId, new IDMContext[] { commandControlCtx });
+ 56:             fLine = line;
+ 57:         }
+
+ 59:         @Override
+ 60:         public boolean equals(Object obj) {
+ 61:             return baseEquals(obj) && (fLine.equals(((BreakpointDMContext) obj).fLine));
+ 62:         }
+
+ 64:         @Override
+ 65:         public int hashCode() {
+ 66:             return baseHashCode() + fLine.hashCode();
+ 67:         }
+
+ 69:         @Override
+ 70:         public String toString() {
+ 71:             return baseToString() + ".breakpoint(" + fLine + ")";  //$NON-NLS-1$//$NON-NLS-2$*/
+ 72:         }
+ 73:     }
+
+ 75:     /**
+ 76:      * Context representing a watch point.  In PDA debugger, a watchpoint is 
+ 77:      * uniquely identified using the function and variable.
+ 78:      */
+ 79:     @Immutable
+ 80:     private static class WatchpointDMContext extends AbstractDMContext implements IBreakpointDMContext {
+ 81:         final String fFunction;
+ 82:         final String fVariable; 
+
+ 84:         public WatchpointDMContext(String sessionId, PDAProgramDMContext commandControlCtx, String function, 
+ 85:             String variable) 
+ 86:         {
+ 87:             super(sessionId, new IDMContext[] { commandControlCtx });
+ 88:             fFunction = function;
+ 89:             fVariable = variable;
+ 90:         }
+
+ 92:         @Override
+ 93:         public boolean equals(Object obj) {
+ 94:             if (baseEquals(obj)) {
+ 95:                 WatchpointDMContext watchpointCtx = (WatchpointDMContext)obj;
+ 96:                 return fFunction.equals(watchpointCtx.fFunction) && fVariable.equals(watchpointCtx.fVariable);
+ 97:             }
+ 98:             return false;
+ 99:         }
+
+101:         @Override
+102:         public int hashCode() {
+103:             return baseHashCode() + fFunction.hashCode() + fVariable.hashCode();
+104:         }
+
+106:         @Override
+107:         public String toString() {
+108:             return baseToString() + ".watchpoint(" + fFunction + "::" + fVariable + ")";
+109:         }
+110:     }
+
+112:     // Attribute names
+113:     public static final String ATTR_BREAKPOINT_TYPE = PDAPlugin.PLUGIN_ID + ".pdaBreakpointType";      //$NON-NLS-1$
+114:     public static final String PDA_LINE_BREAKPOINT = "breakpoint";                 //$NON-NLS-1$
+115:     public static final String PDA_WATCHPOINT = "watchpoint";                 //$NON-NLS-1$
+116:     public static final String ATTR_PROGRAM_PATH = PDAPlugin.PLUGIN_ID + ".pdaProgramPath";      //$NON-NLS-1$
+
+118:     // Services
+119:     private PDACommandControl fCommandControl;
+
+121:     // Breakpoints currently installed
+122:     private Set<IBreakpointDMContext> fBreakpoints = new HashSet<IBreakpointDMContext>();
+
+124:     /**
+125:      * The service constructor
+126:      * 
+127:      * @param session The debugging session this service belongs to.
+128:      */
+129:     public PDABreakpoints(DsfSession session) {
+130:         super(session);
+131:     }
+
+133:     @Override
+134:     public void initialize(final RequestMonitor rm) {
+135:         super.initialize(new RequestMonitor(getExecutor(), rm) {
+136:             @Override
+137:             protected void handleOK() {
+138:                 doInitialize(rm);
+139:             }
+140:         });
+141:     }
+
+143:     private void doInitialize(final RequestMonitor rm) {
+144:         // Get the services references
+145:         fCommandControl = getServicesTracker().getService(PDACommandControl.class);
+
+147:         // Register this service
+148:         register(new String[] { IBreakpoints.class.getName(), PDABreakpoints.class.getName() },
+149:             new Hashtable<String, String>());
+
+151:         rm.done();
+152:     }
+
+154:     @Override
+155:     public void shutdown(final RequestMonitor rm) {
+156:         unregister();
+157:         rm.done();
+158:     }
+
+160:     @Override
+161:     protected BundleContext getBundleContext() {
+162:         return PDAPlugin.getBundleContext();
+163:     }
+
+165:     public void getBreakpoints(final IBreakpointsTargetDMContext context, final DataRequestMonitor<IBreakpointDMContext[]> rm) {
+166:         // Validate the context
+167:         if (!fCommandControl.getProgramDMContext().equals(context)) {
+168:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoints target context");
+169:             return;
+170:         }
+
+172:         rm.setData(fBreakpoints.toArray(new IBreakpointDMContext[fBreakpoints.size()]));
+173:         rm.done();
+174:     }
+
+176:     public void getBreakpointDMData(IBreakpointDMContext dmc, DataRequestMonitor<IBreakpointDMData> rm) {
+177:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Retrieving breakpoint data is not supported");
+178:     }
+
+180:     public void insertBreakpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, 
+181:         DataRequestMonitor<IBreakpointDMContext> rm) 
+182:     {
+183:         Boolean enabled = (Boolean)attributes.get(IBreakpoint.ENABLED);
+184:         if (enabled != null && !enabled.booleanValue()) {
+185:             // If the breakpoint is disabled, just fail the request. 
+186:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint is disabled");
+187:         } else {
+188:             String type = (String) attributes.get(ATTR_BREAKPOINT_TYPE);
+
+190:             if (PDA_LINE_BREAKPOINT.equals(type)) {
+191:                 // Retrieve the PDA program context from the context given in the 
+192:                 // argument.  This service is typically only called by the 
+193:                 // breakpoints mediator, which was called with the program context
+194:                 // in the services initialization sequence.  So checking if 
+195:                 // programCtx != null is mostly a formality.
+196:                 PDAProgramDMContext programCtx = DMContexts.getAncestorOfType(context, PDAProgramDMContext.class);
+197:                 if (programCtx != null) {
+198:                     doInsertBreakpoint(programCtx, attributes, rm);
+199:                 } else {
+200:                     PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown breakpoint type");
+201:                 }
+202:             }
+203:             else if (PDA_WATCHPOINT.equals(type)) {
+204:                 doInsertWatchpoint(attributes, rm);
+205:             }
+206:             else {
+207:                 PDAPlugin.failRequest(rm, REQUEST_FAILED, "Unknown breakpoint type");
+208:             }
+209:         }
+210:     }
+
+212:     private void doInsertBreakpoint(PDAProgramDMContext programCtx, final Map<String, Object> attributes, final DataRequestMonitor<IBreakpointDMContext> rm) 
+213:     {
+214:         // Compare the program path in the breakpoint with the path in the PDA 
+215:         // program context. Only insert the breakpoint if the program matches. 
+216:         String program = (String)attributes.get(ATTR_PROGRAM_PATH);
+217:         if (!programCtx.getProgram().equals(program)) {
+218:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Invalid file name");
+219:             return;
+220:         }
+
+222:         // Retrieve the line.
+223:         Integer line = (Integer)attributes.get(IMarker.LINE_NUMBER);
+224:         if (line == null) {
+225:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "No breakpoint line specified");
+226:             return;
+227:         }
+
+229:         // Create a new breakpoint context object and check that it's not 
+230:         // installed already. PDA can only track a single breakpoint at a 
+231:         // given line, attempting to set the second breakpoint should fail.
+232:         final BreakpointDMContext breakpointCtx = 
+233:             new BreakpointDMContext(getSession().getId(), fCommandControl.getProgramDMContext(), line);
+234:         if (fBreakpoints.contains(breakpointCtx)) {
+235:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already set");
+236:             return;
+237:         }
+
+239:         // Add the new breakpoint context to the list of known breakpoints.  
+240:         // Adding it here, before the set command is completed will prevent 
+241:         // a possibility of a second breakpoint being installed in the same 
+242:         // location while this breakpoint is being processed.  It will also
+243:         // allow the breakpoint to be removed or updated even while it is 
+244:         // still being processed here.
+245:         fBreakpoints.add(breakpointCtx);
+246:         fCommandControl.queueCommand(
+247:             new PDASetBreakpointCommand(fCommandControl.getProgramDMContext(), line), 
+248:             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
+249:                 @Override
+250:                 protected void handleOK() {
+251:                     rm.setData(breakpointCtx);
+252:                     rm.done();
+253:                 }
+
+255:                 @Override
+256:                 protected void handleErrorOrCancel() {
+257:                     // If inserting of the breakpoint failed, remove it from
+258:                     // the set of installed breakpoints.
+259:                     fBreakpoints.remove(breakpointCtx);
+260:                     super.handleErrorOrCancel();
+261:                 }
+262:             });
+263:     }
+
+265:     private void doInsertWatchpoint(final Map<String, Object> attributes, final DataRequestMonitor<IBreakpointDMContext> rm) 
+266:     {
+267:         String function = (String)attributes.get(PDAWatchpoint.FUNCTION_NAME);
+268:         if (function == null) {
+269:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "No function specified");
+270:             return;
+271:         }
+
+273:         String variable = (String)attributes.get(PDAWatchpoint.VAR_NAME);
+274:         if (variable == null) {
+275:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "No variable specified");
+276:             return;
+277:         }
+
+279:         Boolean isAccess = (Boolean)attributes.get(PDAWatchpoint.ACCESS);
+280:         isAccess = isAccess != null ? isAccess : Boolean.FALSE; 
+
+282:         Boolean isModification = (Boolean)attributes.get(PDAWatchpoint.MODIFICATION);
+283:         isModification = isModification != null ? isModification : Boolean.FALSE; 
+
+285:         // Create a new watchpoint context object and check that it's not 
+286:         // installed already. PDA can only track a single watchpoint for a given
+287:         // function::variable, attempting to set the second breakpoint should fail.
+288:         final WatchpointDMContext watchpointCtx = 
+289:             new WatchpointDMContext(getSession().getId(), fCommandControl.getProgramDMContext(), function, variable);
+290:         if (fBreakpoints.contains(watchpointCtx)) {
+291:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Watchpoint already set");
+292:             return;
+293:         }
+
+295:         // Determine the watch operation to perform.
+296:         PDAWatchCommand.WatchOperation watchOperation = PDAWatchCommand.WatchOperation.NONE;
+297:         if (isAccess && isModification) {
+298:             watchOperation = PDAWatchCommand.WatchOperation.BOTH;
+299:         } else if (isAccess) {
+300:             watchOperation = PDAWatchCommand.WatchOperation.READ;
+301:         } else if (isModification) {
+302:             watchOperation = PDAWatchCommand.WatchOperation.WRITE;
+303:         }
+
+305:         // Add the new breakpoint context to the list of known breakpoints.  
+306:         // Adding it here, before the set command is completed will prevent 
+307:         // a possibility of a second breakpoint being installed in the same 
+308:         // location while this breakpoint is being processed.  It will also
+309:         // allow the breakpoint to be removed or updated even while it is 
+310:         // still being processed here.
+311:         fBreakpoints.add(watchpointCtx);
+312:         fCommandControl.queueCommand(
+313:             new PDAWatchCommand(fCommandControl.getProgramDMContext(), function, variable, watchOperation), 
+314:             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
+315:                 @Override
+316:                 protected void handleOK() {
+317:                     rm.setData(watchpointCtx);
+318:                     rm.done();
+319:                 }
+
+321:                 @Override
+322:                 protected void handleErrorOrCancel() {
+323:                     // Since the command failed, we need to remove the breakpoint from 
+324:                     // the existing breakpoint set.
+325:                     fBreakpoints.remove(watchpointCtx);
+326:                     super.handleErrorOrCancel();
+327:                 }
+328:             });
+329:     }
+
+331:     public void removeBreakpoint(IBreakpointDMContext bpCtx, RequestMonitor rm) {
+332:         if (!fBreakpoints.contains(bpCtx)) {
+333:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint already removed");
+334:             return;
+335:         }
+
+337:         if (bpCtx instanceof BreakpointDMContext) {
+338:             doRemoveBreakpoint((BreakpointDMContext)bpCtx, rm);
+339:         } else if (bpCtx instanceof WatchpointDMContext) {
+340:             doRemoveWatchpoint((WatchpointDMContext)bpCtx, rm);
+341:         } else {
+342:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint");
+343:         }
+344:     }
+
+346:     private void doRemoveBreakpoint(BreakpointDMContext bpCtx, RequestMonitor rm) {
+347:         // Remove the breakpoint from the table right away, so that even when 
+348:         // the remove is being processed, a new breakpoint can be created at the same 
+349:         // location.
+350:         fBreakpoints.remove(bpCtx);
+
+352:         fCommandControl.queueCommand(
+353:             new PDAClearBreakpointCommand(fCommandControl.getProgramDMContext(), bpCtx.fLine), 
+354:             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm));        
+355:     }
+
+357:     private void doRemoveWatchpoint(WatchpointDMContext bpCtx, RequestMonitor rm) {
+358:         fBreakpoints.remove(bpCtx);
+
+360:         // Watchpoints are cleared using the same command, but with a "no watch" operation
+361:         fCommandControl.queueCommand(
+362:             new PDAWatchCommand(
+363:                 fCommandControl.getProgramDMContext(), bpCtx.fFunction, bpCtx.fVariable, PDAWatchCommand.WatchOperation.NONE), 
+364:                 new DataRequestMonitor<PDACommandResult>(getExecutor(), rm));        
+365:     }
+
+367:     public void updateBreakpoint(final IBreakpointDMContext bpCtx, Map<String, Object> attributes, final RequestMonitor rm) {
+368:         if (!fBreakpoints.contains(bpCtx)) {
+369:             PDAPlugin.failRequest(rm, REQUEST_FAILED, "Breakpoint not installed");
+370:             return;
+371:         }
+
+373:         if (bpCtx instanceof BreakpointDMContext) {
+374:             PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Modifying PDA breakpoints is not supported");
+375:         } else if (bpCtx instanceof WatchpointDMContext) {
+376:             WatchpointDMContext wpCtx = (WatchpointDMContext)bpCtx;
+377:             if (!wpCtx.fFunction.equals(attributes.get(PDAWatchpoint.FUNCTION_NAME)) || 
+378:                 !wpCtx.fVariable.equals(attributes.get(PDAWatchpoint.VAR_NAME)) )
+379:             {
+380:                 PDAPlugin.failRequest(rm, REQUEST_FAILED, "Cannot modify watchpoint function or variable");
+381:                 return;
+382:             }
+383:             
+384:             // PDA debugger can only track one watchpoint in the same location, 
+385:             // so we can simply remove the existing context from the set and 
+386:             // call insert again.  
+387:             fBreakpoints.remove(bpCtx);
+388:             doInsertWatchpoint(
+389:                 attributes, 
+390:                 new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), rm) {
+391:                     @Override
+392:                     protected void handleOK() {
+393:                         // The inserted watchpoint context will equal the 
+394:                         // current context.
+395:                         assert bpCtx.equals(getData());
+396:                         rm.done();
+397:                     }
+398:                 });
+399:         } else {
+400:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid breakpoint");
+401:         }
+402:     }
+403: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java index d835a549554..e7b77ceeb0d 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java @@ -83,15 +83,20 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon private final List fEventListeners = new ArrayList(); // Sockets for communicating with PDA debugger + @ThreadSafe private Socket fRequestSocket; + @ThreadSafe private PrintWriter fRequestWriter; + @ThreadSafe private BufferedReader fRequestReader; + @ThreadSafe private Socket fEventSocket; + @ThreadSafe private BufferedReader fEventReader; // Jobs servicing the sockets. private EventDispatchJob fEventDispatchJob; - private CommandSendJob fRequestJob; + private CommandSendJob fCommandSendJob; /** * Command control constructor. @@ -170,8 +175,8 @@ public class PDACommandControl extends AbstractDsfService implements ICommandCon fEventDispatchJob = new EventDispatchJob(); fEventDispatchJob.schedule(); - fRequestJob = new CommandSendJob(); - fRequestJob.schedule(); + fCommandSendJob = new CommandSendJob(); + fCommandSendJob.schedule(); socketsInitializeRm.done(); } catch (UnknownHostException e) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java.html new file mode 100644 index 00000000000..556bfa472ed --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDACommandControl.java.html @@ -0,0 +1,547 @@ + + + +PDACommandControl.java + + + + + +
  1: package org.eclipse.dd.examples.pda.service;
+
+  3: import java.io.BufferedReader;
+  4: import java.io.IOException;
+  5: import java.io.InputStreamReader;
+  6: import java.io.PrintWriter;
+  7: import java.net.Socket;
+  8: import java.net.UnknownHostException;
+  9: import java.util.ArrayList;
+ 10: import java.util.Hashtable;
+ 11: import java.util.Iterator;
+ 12: import java.util.LinkedList;
+ 13: import java.util.List;
+ 14: import java.util.concurrent.BlockingQueue;
+ 15: import java.util.concurrent.LinkedBlockingQueue;
+ 16: import java.util.concurrent.RejectedExecutionException;
+
+ 18: import org.eclipse.core.runtime.IProgressMonitor;
+ 19: import org.eclipse.core.runtime.IStatus;
+ 20: import org.eclipse.core.runtime.Status;
+ 21: import org.eclipse.core.runtime.jobs.Job;
+ 22: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+ 23: import org.eclipse.dd.dsf.concurrent.DsfRunnable;
+ 24: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+ 25: import org.eclipse.dd.dsf.concurrent.ThreadSafe;
+ 26: import org.eclipse.dd.dsf.debug.service.command.ICommand;
+ 27: import org.eclipse.dd.dsf.debug.service.command.ICommandControl;
+ 28: import org.eclipse.dd.dsf.debug.service.command.ICommandListener;
+ 29: import org.eclipse.dd.dsf.debug.service.command.ICommandResult;
+ 30: import org.eclipse.dd.dsf.debug.service.command.IEventListener;
+ 31: import org.eclipse.dd.dsf.service.AbstractDsfService;
+ 32: import org.eclipse.dd.dsf.service.DsfSession;
+ 33: import org.eclipse.dd.examples.pda.PDAPlugin;
+ 34: import org.eclipse.dd.examples.pda.service.commands.AbstractPDACommand;
+ 35: import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
+ 36: import org.eclipse.dd.examples.pda.service.commands.PDAExitCommand;
+ 37: import org.osgi.framework.BundleContext;
+
+
+ 40: /**
+ 41:  * Service that handles communication with a PDA debugger back end.  
+ 42:  */
+ 43: public class PDACommandControl extends AbstractDsfService implements ICommandControl {
+
+ 45:     // Structure used to store command information in services internal queues.
+ 46:     private static class CommandHandle {
+ 47:         final private AbstractPDACommand<PDACommandResult> fCommand;
+ 48:         final private DataRequestMonitor<PDACommandResult> fRequestMonitor;
+ 49:         
+ 50:         CommandHandle(AbstractPDACommand<PDACommandResult> c, DataRequestMonitor<PDACommandResult> rm) {
+ 51:             fCommand = c; 
+ 52:             fRequestMonitor = rm;
+ 53:         }
+ 54:     }
+
+ 56:     // Parameters that the command control is created with.
+ 57:     final private String fProgram;
+ 58:     final private int fRequestPort;
+ 59:     final private int fEventPort;
+
+ 61:     // Queue of commands waiting to be sent to the debugger.  As long as commands
+ 62:     // are in this queue, they can still be removed by clients. 
+ 63:     private final List<CommandHandle> fCommandQueue = new LinkedList<CommandHandle>();
+ 64:     
+ 65:     // Queue of commands that are being sent to the debugger.  This queue is read
+ 66:     // by the send job, so as soon as commands are inserted into this queue, they can
+ 67:     // be considered as sent.
+ 68:     @ThreadSafe
+ 69:     private final BlockingQueue<CommandHandle> fTxCommands = new LinkedBlockingQueue<CommandHandle>();
+ 70:     
+ 71:     // Flag indicating that the PDA debugger started
+ 72:     private boolean fStarted = false;
+ 73:     
+ 74:     // Flag indicating that the PDA debugger has been disconnected 
+ 75:     @ThreadSafe
+ 76:     private boolean fTerminated = false;
+ 77:     
+ 78:     //  Data Model context of this command control. 
+ 79:     private PDAProgramDMContext fDMContext;
+
+ 81:     // Synchronous listeners for commands and events.
+ 82:     private final List<ICommandListener> fCommandListeners = new ArrayList<ICommandListener>();
+ 83:     private final List<IEventListener>   fEventListeners = new ArrayList<IEventListener>();
+ 84:     
+ 85:     // Sockets for communicating with PDA debugger 
+ 86:     @ThreadSafe
+ 87:     private Socket fRequestSocket;
+ 88:     @ThreadSafe
+ 89:     private PrintWriter fRequestWriter;
+ 90:     @ThreadSafe
+ 91:     private BufferedReader fRequestReader;
+ 92:     @ThreadSafe
+ 93:     private Socket fEventSocket;
+ 94:     @ThreadSafe
+ 95:     private BufferedReader fEventReader;
+
+ 97:     // Jobs servicing the sockets.
+ 98:     private EventDispatchJob fEventDispatchJob;
+ 99:     private CommandSendJob fCommandSendJob;
+100:     
+101:     /**
+102:      * Command control constructor. 
+103:      * @param session The DSF session that this service is a part of. 
+104:      * @param requestPort Port number for sending PDA commands.
+105:      * @param eventPort Port for listening to PDA events.
+106:      */
+107:     public PDACommandControl(DsfSession session, String program, int requestPort, int eventPort) {
+108:         super(session);
+109:         fProgram = program;
+110:         fRequestPort = requestPort;
+111:         fEventPort = eventPort;
+112:     }
+113:     
+114:     @Override
+115:     public void initialize(final RequestMonitor rm) {
+116:         // Call the super-class to perform initialization first.
+117:         super.initialize( new RequestMonitor(getExecutor(), rm) {
+118:             @Override
+119:             protected void handleOK() {
+120:                 doInitialize(rm);
+121:             }
+122:         });
+123:     }
+
+125:     private void doInitialize(final RequestMonitor rm) {
+126:         // Create the control's data model context.
+127:         fDMContext = new PDAProgramDMContext(getSession().getId(), fProgram);
+
+129:         // Add a listener for PDA events to track the started/terminated state.
+130:         addEventListener(new IEventListener() {
+131:             public void eventReceived(Object output) {
+132:                 if ("started".equals(output)) {
+133:                     setStarted();
+134:                 } else if ("terminated".equals(output)) {
+135:                     setTerminated();
+136:                 }
+137:             }
+138:         });
+139:         
+140:         // Request monitor that will be invoked when the socket initialization is
+141:         // completed.  
+142:         final RequestMonitor socketsInitializeRm = new RequestMonitor(getExecutor(), rm) {
+143:             @Override
+144:             protected void handleOK() {
+145:                 // Register the service with OSGi as the last step in initialization of 
+146:                 // the service.
+147:                 register(
+148:                     new String[]{ ICommandControl.class.getName(), PDACommandControl.class.getName() }, 
+149:                     new Hashtable<String,String>());
+150:                 rm.done();
+151:             }
+152:         };
+153:         
+154:         // To avoid blocking the DSF dispatch thread use a job to initialize communication sockets.  
+155:         new Job("PDA Initialize") {
+156:             @Override
+157:             protected IStatus run(IProgressMonitor monitor) {
+158:                 try {
+159:                     // give interpreter a chance to start
+160:                     try {
+161:                         Thread.sleep(1000);
+162:                     } catch (InterruptedException e) {
+163:                     }
+164:                     fRequestSocket = new Socket("localhost", fRequestPort);
+165:                     fRequestWriter = new PrintWriter(fRequestSocket.getOutputStream());
+166:                     fRequestReader = new BufferedReader(new InputStreamReader(fRequestSocket.getInputStream()));
+167:                     // give interpreter a chance to open next socket
+168:                     try {
+169:                         Thread.sleep(1000);
+170:                     } catch (InterruptedException e) {
+171:                     }
+172:                     fEventSocket = new Socket("localhost", fEventPort);
+173:                     fEventReader = new BufferedReader(new InputStreamReader(fEventSocket.getInputStream()));
+
+175:                     fEventDispatchJob = new EventDispatchJob();
+176:                     fEventDispatchJob.schedule();
+177:                     
+178:                     fCommandSendJob = new CommandSendJob();
+179:                     fCommandSendJob.schedule();
+
+181:                     socketsInitializeRm.done();
+182:                 } catch (UnknownHostException e) {
+183:                     socketsInitializeRm.setStatus(new Status(
+184:                         IStatus.ERROR, PDAPlugin.PLUGIN_ID, REQUEST_FAILED, "Unable to connect to PDA VM", e));
+185:                     socketsInitializeRm.done();
+186:                 } catch (IOException e) {
+187:                     socketsInitializeRm.setStatus(new Status(
+188:                         IStatus.ERROR, PDAPlugin.PLUGIN_ID, REQUEST_FAILED, "Unable to connect to PDA VM", e));
+189:                     socketsInitializeRm.done();
+190:                 }
+191:                 return Status.OK_STATUS;
+192:             }
+193:         }.schedule();
+194:     }
+
+196:     @Override
+197:     public void shutdown(final RequestMonitor requestMonitor) {
+198:         // Unregister the service first, so that clients may no longer gain access to it.
+199:         unregister();
+200:         
+201:         if (!isTerminated()) {
+202:             // If the debugger is still connected, send it the exit command.
+203:             terminate(new RequestMonitor(getExecutor(), requestMonitor) {
+204:                 @Override
+205:                 protected void handleCompleted() {
+206:                     // Mark the command control as terminated.
+207:                     setTerminated();
+
+209:                     // Ignore any error resulting from the exit command.  
+210:                     // Errors will most likely result if the PDA process is 
+211:                     // already terminated.
+212:                     requestMonitor.done();
+213:                 }
+214:             });
+215:         } else {
+216:             requestMonitor.done();
+217:         }
+218:     }        
+
+220:     @Override
+221:     protected BundleContext getBundleContext() {
+222:         return PDAPlugin.getBundleContext();
+223:     }
+224:     
+225:     /**
+226:      *  Job that services the send command queue. 
+227:      */
+228:     private class CommandSendJob extends Job {
+229:         CommandSendJob() {
+230:             super("PDA Command Send");
+231:             setSystem(true);
+232:         }
+233:         
+234:         @Override
+235:         protected IStatus run(IProgressMonitor monitor) {
+236:             while (!isTerminated()) {
+237:                 synchronized(fTxCommands) {
+238:                     try {
+239:                         // Remove comamnd from send queue.
+240:                         final CommandHandle commandHandle = fTxCommands.take();
+241:                         
+242:                         // Send the request to PDA
+243:                         fRequestWriter.println(commandHandle.fCommand.getRequest());
+244:                         fRequestWriter.flush();
+245:                         
+246:                         try {
+247:                             // wait for reply
+248:                             final String response = fRequestReader.readLine();
+249:                             
+250:                             // Process the reply in the executor thread.
+251:                             try {
+252:                                 getExecutor().execute(new DsfRunnable() {
+253:                                     public void run() {
+254:                                         processCommandDone(commandHandle, response);
+255:                                     }
+256:                                 });
+257:                             } catch (RejectedExecutionException e) {
+258:                                 // Acceptable race condition may see the session shut down
+259:                                 // while we're waiting for command response.  Still complete
+260:                                 // the request monitor.
+261:                                 assert isTerminated();
+262:                                 assert isTerminated();
+263:                                 PDAPlugin.failRequest(commandHandle.fRequestMonitor, REQUEST_FAILED, "Command control shut down.");
+264:                             }
+265:                         } catch (final IOException e) {
+266:                             // Process error it in the executor thread
+267:                             try {
+268:                                 getExecutor().execute(new DsfRunnable() {
+269:                                     public void run() {
+270:                                         processCommandException(commandHandle, e);
+271:                                     }
+272:                                 });
+273:                             } catch (RejectedExecutionException re) {
+274:                                 // Acceptable race condition... see above
+275:                                 assert isTerminated();
+276:                                 PDAPlugin.failRequest(commandHandle.fRequestMonitor, REQUEST_FAILED, "Command control shut down.");
+277:                             }
+278:                         }
+279:                     } catch (InterruptedException e) {
+280:                         break;  // Shutting down.
+281:                     }
+282:                 }
+283:             }
+284:             return Status.OK_STATUS;
+285:         }        
+286:         
+287:     }
+288:     
+289:     /**
+290:      * Job that services the PDA event socket.
+291:      */
+292:     class EventDispatchJob extends Job {
+293:         
+294:         public EventDispatchJob() {
+295:             super("PDA Event Listner");
+296:             setSystem(true);
+297:         }
+
+299:         @Override
+300:         protected IStatus run(IProgressMonitor monitor) {
+301:             while (!isTerminated()) {
+302:                 try {
+303:                     // Wait for an event.
+304:                     final String event = fEventReader.readLine();
+305:                     if (event != null) {
+306:                         try {
+307:                             // Process the event in executor thread.
+308:                             getExecutor().execute(new DsfRunnable() {
+309:                                 public void run() {
+310:                                     processEventReceived(event);
+311:                                 }
+312:                             });
+313:                         } catch (RejectedExecutionException e) {}                
+314:                     } else {
+315:                         break;
+316:                     }
+317:                 } catch (IOException e) {
+318:                     break;
+319:                 }
+320:             }
+321:             if (!isTerminated()) {
+322:                 // Exception from the event socket is an indicator that the PDA debugger
+323:                 // has exited.  Call setTerminated() in executor thread.
+324:                 try {
+325:                     getExecutor().execute(new DsfRunnable() {
+326:                         public void run() {
+327:                             setTerminated();
+328:                         }
+329:                     });
+330:                 } catch (RejectedExecutionException e) {}                
+331:             }
+332:             return Status.OK_STATUS;
+333:         }
+334:         
+335:     }
+336:     
+337:     public <V extends ICommandResult> void queueCommand(ICommand<V> command, DataRequestMonitor<V> rm) {
+338:         if (command instanceof AbstractPDACommand<?>) {
+339:             // Cast from command with "<V extends ICommandResult>" to a more concrete
+340:             // type to use internally in the command control.
+341:             @SuppressWarnings("unchecked")
+342:             AbstractPDACommand<PDACommandResult> pdaCommand = (AbstractPDACommand<PDACommandResult>)command;
+343:             
+344:             // Similarly, cast the request monitor to a more concrete type.
+345:             @SuppressWarnings("unchecked")
+346:             DataRequestMonitor<PDACommandResult> pdaRM = (DataRequestMonitor<PDACommandResult>)rm;
+
+348:             // Add the command to the queue and notify command listeners.
+349:             fCommandQueue.add( new CommandHandle(pdaCommand, pdaRM) );
+350:             for (ICommandListener listener : fCommandListeners) {
+351:                 listener.commandQueued(command);
+352:             }
+353:             
+354:             // In a separate dispatch cycle.  This allows command listeners to repond to the 
+355:             // command queued event.  
+356:             getExecutor().execute(new DsfRunnable() {
+357:                 public void run() {
+358:                     processQueues();
+359:                 }
+360:             });
+361:             
+362:         } else {
+363:             PDAPlugin.failRequest(rm, INTERNAL_ERROR, "Unrecognized command: " + command);
+364:         }
+365:     }
+
+367:     public void cancelCommand(ICommand<? extends ICommandResult> command) {
+368:         // This debugger is unable of canceling commands once they have 
+369:         // been sent.
+370:     }
+
+372:     public void removeCommand(ICommand<? extends ICommandResult> command) {
+373:         // Removes given command from the queue and notify the listeners
+374:         for (Iterator<CommandHandle> itr = fCommandQueue.iterator(); itr.hasNext();) {
+375:             CommandHandle handle = itr.next();
+376:             if (command.equals(handle.fCommand)) {
+377:                 itr.remove();
+378:                 for (ICommandListener listener : fCommandListeners) {
+379:                     listener.commandRemoved(command);
+380:                 }                
+381:             }
+382:         }
+383:     }
+384:     
+385:     public void addCommandListener(ICommandListener processor) { 
+386:         fCommandListeners.add(processor); 
+387:     }
+388:     
+389:     public void removeCommandListener(ICommandListener processor) { 
+390:         fCommandListeners.remove(processor); 
+391:     }
+392:     
+393:     public void addEventListener(IEventListener processor) { 
+394:         fEventListeners.add(processor); 
+395:     }
+396:     
+397:     public void removeEventListener(IEventListener processor) { 
+398:         fEventListeners.remove(processor); 
+399:     }
+
+401:     private void processCommandDone(CommandHandle handle, String response) {
+402:         // Trace to debug output.
+403:         PDAPlugin.debug("R: " + response);
+404:         
+405:         // Given the PDA response string, create the result using the command
+406:         // that was sent.
+407:         PDACommandResult result = handle.fCommand.createResult(response);
+408:         
+409:         // Set the result to the request monitor and return to sender.
+410:         // Note: as long as PDA sends some response, a PDA command will never
+411:         // return an error.
+412:         handle.fRequestMonitor.setData(result);
+413:         handle.fRequestMonitor.done();
+
+415:         // Notify listeners of the response
+416:         for (ICommandListener listener : fCommandListeners) {
+417:             listener.commandDone(handle.fCommand, result);
+418:         }
+419:         
+420:         // Process next command in queue.
+421:         processQueues();
+422:     }
+
+424:     
+425:     private void processCommandException(CommandHandle handle, Throwable exception) {
+426:         
+427:         // If sending a command resulted in an exception, notify the client.
+428:         handle.fRequestMonitor.setStatus(new Status(
+429:             IStatus.ERROR, PDAPlugin.PLUGIN_ID, REQUEST_FAILED, "Exception reading request response", exception));
+430:         handle.fRequestMonitor.done();                            
+
+432:         // Notify listeners also.
+433:         for (ICommandListener listener : fCommandListeners) {
+434:             listener.commandDone(handle.fCommand, null);
+435:         }
+436:     }
+
+438:     private void processEventReceived(String event) {
+439:         // Notify the listeners only.
+440:         PDAPlugin.debug("E: " + event);
+441:         for (IEventListener listener : fEventListeners) {
+442:             listener.eventReceived(event);
+443:         }
+444:     }
+445:     
+446:     private synchronized void processQueues() {
+447:         if (isTerminated()) {
+448:             // If the PDA debugger is terminated.  Return all submitted commands 
+449:             // with an error.
+450:             for (CommandHandle handle : fCommandQueue) {
+451:                 handle.fRequestMonitor.setStatus(new Status(
+452:                     IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_STATE, "Command control is terminated", null));
+453:                 handle.fRequestMonitor.done();
+454:             }
+455:             fCommandQueue.clear();
+456:         } else if (fStarted && fTxCommands.isEmpty() && !fCommandQueue.isEmpty()) {
+457:             // Process the queues if:
+458:             // - the PDA debugger has started,
+459:             // - there are no pending commands in the send queue,
+460:             // - and there are commands waiting to be sent.
+461:             CommandHandle handle = fCommandQueue.remove(0); 
+462:             fTxCommands.add(handle);
+463:             PDAPlugin.debug("C: " + handle.fCommand.getRequest());
+464:             for (ICommandListener listener : fCommandListeners) {
+465:                 listener.commandSent(handle.fCommand);
+466:             }            
+467:         }
+468:     }
+469:     
+470:     /**
+471:      * Return the PDA Debugger top-level Data Model context. 
+472:      * @see PDAProgramDMContext
+473:      */
+474:     @ThreadSafe
+475:     public PDAProgramDMContext getProgramDMContext() {
+476:         return fDMContext;
+477:     }
+
+479:     private void setStarted() {
+480:         // Mark the command control as started and ready to process commands.
+481:         fStarted = true;
+482:         
+483:         // Process any commands which may have been queued before the 
+484:         processQueues();
+
+486:         // Issue a data model event.
+487:         getSession().dispatchEvent(new PDAStartedEvent(getProgramDMContext()), getProperties());
+488:     }
+489:     
+490:     /**
+491:      * Returns whether the PDA debugger has started and is processing commands.
+492:      */
+493:     public boolean isStarted() {
+494:         return fStarted;
+495:     }
+496:     
+497:     @ThreadSafe
+498:     private synchronized void setTerminated() {
+499:         // Set terminated may be called more than once: by event listener thread, 
+500:         // by the terminate command, etc, so protect against sending events multiple
+501:         // times.
+502:         if (!fTerminated) {
+503:             fTerminated = true;
+504:             
+505:             // Process any waiting commands, they all should return with an error.
+506:             processQueues();
+507:             
+508:             // Issue a data model event.
+509:             getSession().dispatchEvent(new PDATerminatedEvent(getProgramDMContext()), getProperties());
+510:         }
+511:     }
+
+513:     /**
+514:      * Returns whether the PDA debugger has been terminated.
+515:      */
+516:     @ThreadSafe
+517:     public synchronized boolean isTerminated() {
+518:         return fTerminated;
+519:     }
+
+521:     /**
+522:      * Sends a command to PDA debugger to terminate.
+523:      */
+524:     public void terminate(RequestMonitor rm) {
+525:         if (!isTerminated()) {
+526:             queueCommand(
+527:                 new PDAExitCommand(fDMContext),
+528:                 new DataRequestMonitor<PDACommandResult>(getExecutor(), rm));
+529:         } else {
+530:             // If already terminated, indicate success.
+531:             rm.done();
+532:         }
+533:     }    
+534: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java.html new file mode 100644 index 00000000000..8292629dd69 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java.html @@ -0,0 +1,386 @@ + + + +PDAExpressions.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2008 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *******************************************************************************/
+ 11: package org.eclipse.dd.examples.pda.service;
+
+ 13: import java.util.Hashtable;
+ 14: import java.util.Map;
+
+ 16: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+ 17: import org.eclipse.dd.dsf.concurrent.Immutable;
+ 18: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+ 19: import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
+ 20: import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
+ 21: import org.eclipse.dd.dsf.datamodel.DMContexts;
+ 22: import org.eclipse.dd.dsf.datamodel.IDMContext;
+ 23: import org.eclipse.dd.dsf.debug.service.IExpressions;
+ 24: import org.eclipse.dd.dsf.debug.service.IStack;
+ 25: import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext;
+ 26: import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
+ 27: import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
+ 28: import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
+ 29: import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
+ 30: import org.eclipse.dd.dsf.debug.service.command.CommandCache;
+ 31: import org.eclipse.dd.dsf.service.AbstractDsfService;
+ 32: import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
+ 33: import org.eclipse.dd.dsf.service.DsfSession;
+ 34: import org.eclipse.dd.examples.pda.PDAPlugin;
+ 35: import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
+ 36: import org.eclipse.dd.examples.pda.service.commands.PDASetVarCommand;
+ 37: import org.eclipse.dd.examples.pda.service.commands.PDAVarCommand;
+ 38: import org.osgi.framework.BundleContext;
+
+ 40: /**
+ 41:  * 
+ 42:  */
+ 43: public class PDAExpressions extends AbstractDsfService implements IExpressions {
+
+ 45:     @Immutable
+ 46:     private static class ExpressionDMContext extends AbstractDMContext implements IExpressionDMContext {
+
+ 48:         final private String fExpression;
+ 49:         
+ 50:         ExpressionDMContext(String sessionId, IFrameDMContext frameDmc, String expressin) {
+ 51:             super(sessionId, new IDMContext[] { frameDmc });
+ 52:             fExpression = expressin;
+ 53:         }
+
+ 55:         public String getExpression() { 
+ 56:             return fExpression;
+ 57:         }
+ 58:         
+ 59:         @Override
+ 60:         public boolean equals(Object other) {
+ 61:             return super.baseEquals(other) && ((ExpressionDMContext)other).fExpression.equals(fExpression);
+ 62:         }
+ 63:         
+ 64:         @Override
+ 65:         public int hashCode() {
+ 66:             return super.baseHashCode() + fExpression.hashCode();
+ 67:         }
+ 68:         
+ 69:         @Override
+ 70:         public String toString() { 
+ 71:             return baseToString() + ".expression(" + fExpression + ")";  
+ 72:         }
+ 73:     }
+
+ 75:     /**
+ 76:      * PDA expressions are simply variables.  Only the variable name 
+ 77:      * is relevant for its data.
+ 78:      */
+ 79:     @Immutable
+ 80:     private static class ExpressionDMData implements IExpressionDMData {
+
+ 82:         final private String fExpression;
+ 83:         
+ 84:         public ExpressionDMData(String expression) {
+ 85:             fExpression = expression;
+ 86:         }
+ 87:         
+ 88:         public BasicType getBasicType() {
+ 89:             return BasicType.basic;
+ 90:         }
+
+ 92:         public String getEncoding() {
+ 93:             return null;
+ 94:         }
+
+ 96:         public Map<String, Integer> getEnumerations() {
+ 97:             return null;
+ 98:         }
+
+100:         public String getName() {
+101:             return fExpression;
+102:         }
+
+104:         public IRegisterDMContext getRegister() {
+105:             return null;
+106:         }
+
+108:         public String getStringValue() {
+109:             return null;
+110:         }
+
+112:         public String getTypeId() {
+113:             return null;
+114:         }
+
+116:         public String getTypeName() {
+117:             return null;
+118:         }
+
+120:     }
+
+122:     // @see #createExpression()
+123:     @Immutable
+124:     private static class InvalidExpressionDMContext extends AbstractDMContext implements IExpressionDMContext {
+125:         final private String fExpression;
+126:     
+127:         public InvalidExpressionDMContext(String sessionId, IDMContext parent, String expr) {
+128:             super(sessionId, new IDMContext[] { parent });
+129:             fExpression = expr;
+130:         }
+131:     
+132:         @Override
+133:         public boolean equals(Object other) {
+134:             return super.baseEquals(other) && 
+135:                 fExpression == null 
+136:                     ? ((InvalidExpressionDMContext) other).getExpression() == null 
+137:                     : fExpression.equals(((InvalidExpressionDMContext) other).getExpression());
+138:         }
+139:     
+140:         @Override
+141:         public int hashCode() {
+142:             return fExpression == null ? super.baseHashCode() : super.baseHashCode() ^ fExpression.hashCode();
+143:         }
+144:     
+145:         @Override
+146:         public String toString() {
+147:             return baseToString() + ".invalid_expr[" + fExpression + "]"; 
+148:         }
+149:     
+150:         public String getExpression() {
+151:             return fExpression;
+152:         }
+153:     }
+154:     
+155:     @Immutable
+156:     private static class ExpressionChangedDMEvent extends AbstractDMEvent<IExpressionDMContext> 
+157:         implements IExpressionChangedDMEvent 
+158:     {
+159:         ExpressionChangedDMEvent(IExpressionDMContext expression) {
+160:             super(expression);
+161:         }
+162:     }
+
+164:     
+165:     private PDACommandControl fCommandControl;
+166:     private IStack fStack;
+
+168:     private CommandCache fCommandCache;
+
+170:     public PDAExpressions(DsfSession session) {
+171:         super(session);
+172:     }
+
+174:     @Override
+175:     protected BundleContext getBundleContext() {
+176:         return PDAPlugin.getBundleContext();
+177:     }
+
+179:     @Override
+180:     public void initialize(final RequestMonitor rm) {
+181:         super.initialize(
+182:             new RequestMonitor(getExecutor(), rm) { 
+183:                 @Override
+184:                 protected void handleOK() {
+185:                     doInitialize(rm);
+186:                 }});
+187:     }
+
+189:     private void doInitialize(final RequestMonitor rm) {
+190:         fCommandControl = getServicesTracker().getService(PDACommandControl.class);
+191:         fStack = getServicesTracker().getService(IStack.class);
+192:         fCommandCache = new CommandCache(fCommandControl);
+
+194:         getSession().addServiceEventListener(this, null);
+195:         
+196:         register(new String[]{IExpressions.class.getName(), PDAExpressions.class.getName()}, new Hashtable<String,String>());
+197:         
+198:         rm.done();
+199:     }
+
+201:     @Override
+202:     public void shutdown(final RequestMonitor rm) {
+203:         getSession().removeServiceEventListener(this);
+204:         fCommandCache.reset();
+205:         super.shutdown(rm);
+206:     }
+
+208:     public void canWriteExpression(IExpressionDMContext expressionContext, DataRequestMonitor<Boolean> rm) {
+209:         rm.setData(true);
+210:         rm.done();
+211:     }
+
+213:     public IExpressionDMContext createExpression(IDMContext ctx, String expression) {
+214:         // Create an expression based on the given context and string expression.  
+215:         // The PDA debugger can only evaluate variables as expressions and only
+216:         // in context of a frame.  
+217:         IFrameDMContext frameCtx = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class);
+218:         if (frameCtx != null) {
+219:             return new ExpressionDMContext(getSession().getId(), frameCtx, expression);
+220:         } else {
+221:             // If a frame cannot be found in context, return an "invalid" 
+222:             // expression context, because a null return value is not allowed.
+223:             // Evaluating an invalid expression context will always yield an 
+224:             // error.
+225:             return new InvalidExpressionDMContext(getSession().getId(), ctx, expression);
+226:         }
+227:     }
+
+229:     public void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor<IExpressionDMContext[]> rm) {
+230:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
+231:     }
+
+233:     public void getExpressionAddressData(IExpressionDMContext dmc, DataRequestMonitor<IExpressionDMAddress> rm) {
+234:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
+235:     }
+
+237:     public void getExpressionData(final IExpressionDMContext exprCtx, final DataRequestMonitor<IExpressionDMData> rm) {
+238:         // Since expression data doesn't contain any more information than the 
+239:         // context, it doesn't require any debugger commmands.
+240:         if (exprCtx instanceof ExpressionDMContext) {
+241:             rm.setData(new ExpressionDMData(exprCtx.getExpression()));
+242:             rm.done();
+243:         } else {
+244:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + exprCtx);
+245:         }
+246:     }
+
+248:     public void getSubExpressionCount(IExpressionDMContext exprCtx, DataRequestMonitor<Integer> rm) {
+249:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
+250:     }
+
+252:     public void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor<IExpressionDMContext[]> rm) {
+253:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
+254:     }
+
+256:     public void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length,
+257:         DataRequestMonitor<IExpressionDMContext[]> rm) 
+258:     {
+259:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
+260:     }
+
+262:     public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm) {
+263:         // PDA debugger doesn't support formatting the expression.  Natural 
+264:         // formatting is the only available option.
+265:         rm.setData(new String[] { NATURAL_FORMAT });
+266:         rm.done();
+267:     }
+
+269:     public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext exprCtx, String formatId) {
+270:         // Creates a context that can be used to retrieve a formatted value.
+271:         return new FormattedValueDMContext(this, exprCtx, formatId);
+272:     }
+
+274:     public void getFormattedExpressionValue(FormattedValueDMContext formattedCtx, 
+275:         final DataRequestMonitor<FormattedValueDMData> rm) 
+276:     {
+277:         final ExpressionDMContext exprCtx = DMContexts.getAncestorOfType(formattedCtx, ExpressionDMContext.class);
+278:         if (exprCtx != null) {
+279:             final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class);
+280:             
+281:             // First retrieve the stack depth, needed to properly calculate
+282:             // the frame index that is used by the PDAVarCommand. 
+283:             fStack.getStackDepth(
+284:                 frameCtx, 0,
+285:                 new DataRequestMonitor<Integer>(getExecutor(), rm) {
+286:                     @Override
+287:                     protected void handleOK() {
+288:                         // Calculate the frame index.
+289:                         int frameId = getData() - frameCtx.getLevel() - 1;
+290:                         
+291:                         // Send the command to evaluate the variable.
+292:                         fCommandCache.execute(
+293:                             new PDAVarCommand(fCommandControl.getProgramDMContext(), frameId, exprCtx.getExpression()), 
+294:                             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
+295:                                 @Override
+296:                                 protected void handleOK() {
+297:                                     rm.setData(new FormattedValueDMData(getData().fResponseText));
+298:                                     rm.done();
+299:                                 }
+300:                             });        
+301:                     }
+302:                 });
+303:         } else {
+304:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + formattedCtx);
+305:             rm.done();
+306:         }
+307:     }
+
+309:     public void writeExpression(final IExpressionDMContext exprCtx, final String exprValue, String formatId, 
+310:         final RequestMonitor rm) 
+311:     {
+312:         if (exprCtx instanceof ExpressionDMContext) {
+313:             final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class);
+314:             
+315:             // Similarly to retrieving the variable, retrieve the 
+316:             // stack depth first.
+317:             fStack.getStackDepth(
+318:                 frameCtx, 0,
+319:                 new DataRequestMonitor<Integer>(getExecutor(), rm) {
+320:                     @Override
+321:                     protected void handleOK() {
+322:                         // Calculate the frame index.
+323:                         int frameId = getData() - frameCtx.getLevel() - 1;
+324:                         
+325:                         // Send the "write" command to PDA debugger
+326:                         fCommandCache.execute(
+327:                             new PDASetVarCommand(fCommandControl.getProgramDMContext(), frameId, exprCtx.getExpression(), exprValue), 
+328:                             new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
+329:                                 @Override
+330:                                 protected void handleOK() {
+331:                                     getSession().dispatchEvent(new ExpressionChangedDMEvent(exprCtx), getProperties());
+332:                                     rm.done();
+333:                                 }
+334:                             });
+335:                     }
+336:                 });
+337:         } else {
+338:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + exprCtx);
+339:             rm.done();
+340:         }
+341:     }
+
+343:     @SuppressWarnings("unchecked")
+344:     @Deprecated
+345:     public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
+346:         if (dmc instanceof IExpressionDMContext) {
+347:             getExpressionData((IExpressionDMContext) dmc, (DataRequestMonitor<IExpressionDMData>) rm);
+348:         } else if (dmc instanceof FormattedValueDMContext) {
+349:             getFormattedExpressionValue((FormattedValueDMContext) dmc, (DataRequestMonitor<FormattedValueDMData>) rm);
+350:         } else {
+351:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown DMC type");
+352:             rm.done();
+353:         }
+354:     }
+
+356:     @DsfServiceEventHandler 
+357:     public void eventDispatched(IResumedDMEvent e) {
+358:         // Mark the cache as not available, so that data retrieval commands 
+359:         // will fail.  Also reset the cache unless it was a step command.
+360:         fCommandCache.setTargetAvailable(false);
+361:         if (!e.getReason().equals(StateChangeReason.STEP)) {
+362:             fCommandCache.reset();
+363:         }
+364:     }    
+
+
+367:     @DsfServiceEventHandler 
+368:     public void eventDispatched(ISuspendedDMEvent e) {
+369:         // Enable sending commands to target and clear the cache.
+370:         fCommandCache.setTargetAvailable(true);
+371:         fCommandCache.reset();
+372:     }
+373: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java index 62a59002dfa..bf4fbedf66b 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java @@ -182,7 +182,7 @@ public class PDARunControl extends AbstractDsfService if (!(output instanceof String)) return; String event = (String)output; - // Handle PDA debugger suspende/resumed events and issue the + // Handle PDA debugger suspended/resumed events and issue the // corresponding Data Model events. Do not update the state // information until we start dispatching the service events. if (event.startsWith("suspended")) { @@ -248,6 +248,7 @@ public class PDARunControl extends AbstractDsfService // If the resume command failed, we no longer // expect to receive a resumed event. fResumePending = false; + super.handleErrorOrCancel(); } } ); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java.html new file mode 100644 index 00000000000..00690033f51 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARunControl.java.html @@ -0,0 +1,330 @@ + + + +PDARunControl.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2006 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *     Ericsson        AB                  - Modified for handling of multiple threads
+ 11:  *******************************************************************************/
+ 12: package org.eclipse.dd.examples.pda.service;
+
+ 14: import java.util.Hashtable;
+
+ 16: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+ 17: import org.eclipse.dd.dsf.concurrent.Immutable;
+ 18: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+ 19: import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
+ 20: import org.eclipse.dd.dsf.datamodel.IDMContext;
+ 21: import org.eclipse.dd.dsf.datamodel.IDMEvent;
+ 22: import org.eclipse.dd.dsf.debug.service.IRunControl;
+ 23: import org.eclipse.dd.dsf.debug.service.command.IEventListener;
+ 24: import org.eclipse.dd.dsf.service.AbstractDsfService;
+ 25: import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
+ 26: import org.eclipse.dd.dsf.service.DsfSession;
+ 27: import org.eclipse.dd.dsf.service.IDsfService;
+ 28: import org.eclipse.dd.examples.pda.PDAPlugin;
+ 29: import org.eclipse.dd.examples.pda.service.commands.PDACommandResult;
+ 30: import org.eclipse.dd.examples.pda.service.commands.PDAResumeCommand;
+ 31: import org.eclipse.dd.examples.pda.service.commands.PDAStepCommand;
+ 32: import org.eclipse.dd.examples.pda.service.commands.PDASuspendCommand;
+ 33: import org.osgi.framework.BundleContext;
+
+
+ 36: /**
+ 37:  * Service for monitoring and controlling execution state of the DPA 
+ 38:  * program.
+ 39:  * <p>
+ 40:  * This service depends on the {@link PDACommandControl} service.
+ 41:  * It must be initialized before this service is initialized.
+ 42:  * </p>
+ 43:  */
+ 44: public class PDARunControl extends AbstractDsfService 
+ 45:     implements IRunControl, IEventListener
+ 46: {
+ 47:     // Implementation note about tracking execution state:
+ 48:     // This class implements event handlers for the events that are generated by 
+ 49:     // this service itself.  When the event is dispatched, these handlers will
+ 50:     // be called first, before any of the clients.  These handlers update the 
+ 51:     // service's internal state information to make them consistent with the 
+ 52:     // events being issued.  Doing this in the handlers as opposed to when 
+ 53:     // the events are generated, guarantees that the state of the service will
+ 54:     // always be consistent with the events.
+ 55:     // The purpose of this pattern is to allow clients that listen to service 
+ 56:     // events and track service state, to be perfectly in sync with the service
+ 57:     // state.
+ 58:     
+ 59:     @Immutable 
+ 60:     private static class ExecutionDMData implements IExecutionDMData {
+ 61:         private final StateChangeReason fReason;
+ 62:         ExecutionDMData(StateChangeReason reason) {
+ 63:             fReason = reason;
+ 64:         }
+ 65:         public StateChangeReason getStateChangeReason() { return fReason; }
+ 66:     }
+ 67:     
+ 68:     @Immutable 
+ 69:     private static class ResumedEvent extends AbstractDMEvent<IExecutionDMContext> 
+ 70:         implements IResumedDMEvent
+ 71:     {
+ 72:         private final String fPDAEvent;
+
+ 74:         ResumedEvent(IExecutionDMContext ctx, String pdaEvent) { 
+ 75:             super(ctx);
+ 76:             fPDAEvent = pdaEvent;
+ 77:         }
+ 78:         
+ 79:         public StateChangeReason getReason() {
+ 80:             if (fPDAEvent.startsWith("resumed breakpoint") || fPDAEvent.startsWith("suspended watch")) {
+ 81:                 return StateChangeReason.BREAKPOINT;
+ 82:             } else if (fPDAEvent.equals("resumed step") || fPDAEvent.equals("resumed drop")) {
+ 83:                 return StateChangeReason.STEP;
+ 84:             } else if (fPDAEvent.equals("resumed client")) {
+ 85:                 return StateChangeReason.USER_REQUEST;
+ 86:             } else {
+ 87:                 return StateChangeReason.UNKNOWN;
+ 88:             } 
+ 89:         }
+ 90:     }
+ 91:     
+ 92:     @Immutable
+ 93:     private static class SuspendedEvent extends AbstractDMEvent<IExecutionDMContext> 
+ 94:         implements ISuspendedDMEvent
+ 95:     {
+ 96:         private final String fPDAEvent;
+ 97:         
+ 98:         SuspendedEvent(IExecutionDMContext ctx, String pdaEvent) { 
+ 99:             super(ctx);
+100:             fPDAEvent = pdaEvent;
+101:         }
+102:         
+103:         public StateChangeReason getReason() {
+104:             if (fPDAEvent.startsWith("suspended breakpoint") || fPDAEvent.startsWith("suspended watch")) {
+105:                 return StateChangeReason.BREAKPOINT;
+106:             } else if (fPDAEvent.equals("suspended step") || fPDAEvent.equals("suspended drop")) {
+107:                 return StateChangeReason.STEP;
+108:             } else if (fPDAEvent.equals("suspended client")) {
+109:                 return StateChangeReason.USER_REQUEST;
+110:             } else {
+111:                 return StateChangeReason.UNKNOWN;
+112:             } 
+113:         }
+114:     }
+
+116:     // Services 
+117:     private PDACommandControl fCommandControl;
+118:     
+119:     // State flags
+120:         private boolean fSuspended = true;
+121:     private boolean fResumePending = false;
+122:         private boolean fStepping = false;
+123:         private StateChangeReason fStateChangeReason;
+124:         
+125:     public PDARunControl(DsfSession session) {
+126:         super(session);
+127:     }
+128:     
+129:     @Override
+130:     protected BundleContext getBundleContext() {
+131:         return PDAPlugin.getBundleContext();
+132:     }
+133:     
+134:     @Override
+135:     public void initialize(final RequestMonitor rm) {
+136:         super.initialize(
+137:             new RequestMonitor(getExecutor(), rm) { 
+138:                 @Override
+139:                 protected void handleOK() {
+140:                     doInitialize(rm);
+141:                 }});
+142:     }
+
+144:     private void doInitialize(final RequestMonitor rm) {
+145:         fCommandControl = getServicesTracker().getService(PDACommandControl.class);
+
+147:         // Add ourselves as a listener to PDA events, to catch suspended/resumed 
+148:         // events.
+149:         fCommandControl.addEventListener(this);
+150:         
+151:         // Add ourselves as a listener to service events, in order to process
+152:         // our own suspended/resumed events.
+153:         getSession().addServiceEventListener(this, null);
+154:         
+155:         // Register the service with OSGi
+156:         register(new String[]{IRunControl.class.getName(), PDARunControl.class.getName()}, new Hashtable<String,String>());
+157:         
+158:         rm.done();
+159:     }
+
+161:     @Override
+162:     public void shutdown(final RequestMonitor rm) {
+163:         fCommandControl.removeEventListener(this);
+164:         getSession().removeServiceEventListener(this);
+165:         super.shutdown(rm);
+166:     }
+167:     
+168:     @Deprecated
+169:     @SuppressWarnings("unchecked")
+170:     public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
+171:         // The getModelData() is deprecated and clients are expected to switch
+172:         // to getExecutionData() and other data retrieve methods directly.
+173:         // However the UI cache still uses it for now.
+174:         if (dmc instanceof IExecutionDMContext) {
+175:             getExecutionData((IExecutionDMContext)dmc, (DataRequestMonitor<IExecutionDMData>)rm); 
+176:         } else {
+177:             PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown DMC type");
+178:         }
+179:     }
+180:     
+181:     public void eventReceived(Object output) {
+182:         if (!(output instanceof String)) return;
+183:         String event = (String)output;
+184:         
+185:         // Handle PDA debugger suspended/resumed events and issue the 
+186:         // corresponding Data Model events.  Do not update the state
+187:         // information until we start dispatching the service events.
+188:         if (event.startsWith("suspended")) {
+189:             IDMEvent<?> dmEvent = new SuspendedEvent(fCommandControl.getProgramDMContext(), event);
+190:             getSession().dispatchEvent(dmEvent, getProperties());
+191:         } else if (event.startsWith("resumed")) {
+192:             IDMEvent<?> dmEvent = new ResumedEvent(fCommandControl.getProgramDMContext(), event);
+193:             getSession().dispatchEvent(dmEvent, getProperties());
+194:         }
+195:     }
+196:     
+197:     
+198:     @DsfServiceEventHandler 
+199:     public void eventDispatched(ResumedEvent e) {
+200:         // This service should be the first to receive the ResumedEvent, 
+201:         // (before any other listeners are called).  Here, update the
+202:         // service state information based on the the resumed event.
+203:         fSuspended = false;
+204:         fResumePending = false;
+205:         fStateChangeReason = e.getReason();
+206:         fStepping = e.getReason().equals(StateChangeReason.STEP);
+207:     }    
+
+
+210:     @DsfServiceEventHandler 
+211:     public void eventDispatched(SuspendedEvent e) {
+212:         // This service should be the first to receive the SuspendedEvent also, 
+213:         // (before any other listeners are called).  Here, update the
+214:         // service state information based on the the suspended event.
+215:         fStateChangeReason = e.getReason();
+216:         fResumePending = false;
+217:         fSuspended = true;
+218:         fStepping = false;
+219:     }
+220:     
+221:     
+222:         public boolean canResume(IExecutionDMContext context) {
+223:         return isSuspended(context) && !fResumePending;
+224:         }
+
+226:         public boolean canSuspend(IExecutionDMContext context) {
+227:         return !isSuspended(context);
+228:         }
+
+230:         public boolean isSuspended(IExecutionDMContext context) {
+231:                 return fSuspended;
+232:         }
+
+234:         public boolean isStepping(IExecutionDMContext context) {
+235:             return !isSuspended(context) && fStepping;
+236:     }
+
+238:         public void resume(IExecutionDMContext context, final RequestMonitor rm) {
+239:                 assert context != null;
+
+241:                 if (canResume(context)) { 
+242:             fResumePending = true;
+243:             fCommandControl.queueCommand(
+244:                     new PDAResumeCommand(fCommandControl.getProgramDMContext()),
+245:                     new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) { 
+246:                     @Override
+247:                     protected void handleErrorOrCancel() {
+248:                         // If the resume command failed, we no longer
+249:                         // expect to receive a resumed event.
+250:                         fResumePending = false;
+251:                     }
+252:                     }
+253:             );
+254:         }else {
+255:             PDAPlugin.failRequest(rm, INVALID_STATE, "Given context: " + context + ", is already running.");
+256:         }
+257:         }
+258:         
+259:         public void suspend(IExecutionDMContext context, final RequestMonitor rm){
+260:                 assert context != null;
+
+262:                 if (canSuspend(context)) {
+263:             fCommandControl.queueCommand(
+264:                 new PDASuspendCommand(fCommandControl.getProgramDMContext()),
+265:                 new DataRequestMonitor<PDACommandResult>(getExecutor(), rm));
+266:             
+267:         } else {
+268:             PDAPlugin.failRequest(rm, IDsfService.INVALID_STATE, "Given context: " + context + ", is already suspended."); 
+269:         }
+270:     }
+271:     
+272:     public boolean canStep(IExecutionDMContext context) {
+273:         return canResume(context);
+274:     }
+275:     
+276:     public void step(IExecutionDMContext context, StepType stepType, final RequestMonitor rm) {
+277:             assert context != null;
+278:             
+279:             if (canResume(context)) {
+280:             fResumePending = true;
+281:             fStepping = true;
+
+283:             fCommandControl.queueCommand(
+284:                 new PDAStepCommand(fCommandControl.getProgramDMContext()),
+285:                 new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
+286:                     @Override
+287:                     protected void handleErrorOrCancel() {
+288:                         // If the step command failed, we no longer
+289:                         // expect to receive a resumed event.
+290:                         fResumePending = false;
+291:                         fStepping = false;
+292:                     }
+293:                 });
+
+295:             } else {
+296:             PDAPlugin.failRequest(rm, INVALID_STATE, "Cannot resume context"); 
+297:             return;
+298:         }
+299:     }
+
+301:     public boolean canInstructionStep(IExecutionDMContext context) {
+302:         return false;
+303:     }
+304:     
+305:     public void instructionStep(IExecutionDMContext context, StepType stepType, RequestMonitor rm) {
+306:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Operation not implemented"); 
+307:     }
+
+309:     public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor<IExecutionDMContext[]> rm) {
+310:         PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Operation not implemented"); 
+311:     }
+312:     
+313:         public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor<IExecutionDMData> rm){
+314:         rm.setData( new ExecutionDMData(fStateChangeReason) );
+315:         rm.done();
+316:     }
+317: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java index f85e2f9e52f..6aa231cc771 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java @@ -54,24 +54,24 @@ public class PDAStack extends AbstractDsfService implements IStack { private static class FrameDMContext extends AbstractDMContext implements IFrameDMContext { final private int fLevel; - + FrameDMContext(String sessionId, IExecutionDMContext execDmc, int level) { super(sessionId, new IDMContext[] { execDmc }); fLevel = level; } public int getLevel() { return fLevel; } - + @Override public boolean equals(Object other) { return super.baseEquals(other) && ((FrameDMContext)other).fLevel == fLevel; } - + @Override public int hashCode() { return super.baseHashCode() ^ fLevel; } - + @Override public String toString() { return baseToString() + ".frame[" + fLevel + "]"; //$NON-NLS-1$ //$NON-NLS-2$ @@ -85,11 +85,11 @@ public class PDAStack extends AbstractDsfService implements IStack { private static class FrameDMData implements IFrameDMData { final private PDAFrame fFrame; - + FrameDMData(PDAFrame frame) { fFrame = frame; } - + public String getFile() { return fFrame.fFilePath.lastSegment(); } @@ -118,24 +118,24 @@ public class PDAStack extends AbstractDsfService implements IStack { private static class VariableDMContext extends AbstractDMContext implements IVariableDMContext { final private String fVariable; - + VariableDMContext(String sessionId, IFrameDMContext frameCtx, String variable) { super(sessionId, new IDMContext[] { frameCtx }); fVariable = variable; - } - + } + String getVariable() { return fVariable; } - + @Override public boolean equals(Object other) { return super.baseEquals(other) && ((VariableDMContext)other).fVariable.equals(fVariable); } - + @Override public int hashCode() { return super.baseHashCode() + fVariable.hashCode(); } - + @Override public String toString() { return baseToString() + ".variable(" + fVariable + ")"; //$NON-NLS-1$ //$NON-NLS-2$ @@ -149,11 +149,11 @@ public class PDAStack extends AbstractDsfService implements IStack { private static class VariableDMData implements IVariableDMData { final private String fVariable; - + VariableDMData(String variable) { fVariable = variable; } - + public String getName() { return fVariable; } @@ -193,16 +193,16 @@ public class PDAStack extends AbstractDsfService implements IStack { // Initialize service references that stack service depends on fCommandControl = getServicesTracker().getService(PDACommandControl.class); fRunControl = getServicesTracker().getService(IRunControl.class); - + // Create the commands cache fCommandCache = new CommandCache(fCommandControl); // Register to listen for run control events, to clear cache accordingly. getSession().addServiceEventListener(this, null); - + // Register stack service with OSGi register(new String[]{IStack.class.getName(), PDAStack.class.getName()}, new Hashtable()); - + rm.done(); } @@ -213,7 +213,7 @@ public class PDAStack extends AbstractDsfService implements IStack { super.shutdown(rm); } - + public void getArguments(IFrameDMContext frameCtx, DataRequestMonitor rm) { PDAPlugin.failRequest(rm, IDsfService.NOT_SUPPORTED, "PDA debugger does not support function arguments."); } @@ -232,7 +232,7 @@ public class PDAStack extends AbstractDsfService implements IStack { PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx); return; } - + // Create the frame data object based on the corresponding PDAFrame rm.setData(new FrameDMData(getData().fFrames[frameId])); rm.done(); @@ -240,7 +240,7 @@ public class PDAStack extends AbstractDsfService implements IStack { }); } - + public void getFrames(IDMContext context, final DataRequestMonitor rm) { // Can only create stack frames for an execution context as a parent, // however the argument context is a generic context type, so it could @@ -251,7 +251,7 @@ public class PDAStack extends AbstractDsfService implements IStack { PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context); return; } - + // Execute the stack command and create the corresponding frame contexts. fCommandCache.execute( new PDAStackCommand(fCommandControl.getProgramDMContext()), @@ -282,7 +282,7 @@ public class PDAStack extends AbstractDsfService implements IStack { return; } PDAFrame pdaFrame = getData().fFrames[frameId]; - + // Create variable contexts for all variables in frame. IVariableDMContext[] variableCtxs = new IVariableDMContext[pdaFrame.fVariables.length]; for (int i = 0; i < pdaFrame.fVariables.length; i++) { @@ -334,7 +334,7 @@ public class PDAStack extends AbstractDsfService implements IStack { // The variable data doen't contain a value. So there's no need to // go to the back end to retrieve it. String variable = ((VariableDMContext)variableCtx).getVariable(); - + rm.setData(new VariableDMData(variable)); rm.done(); } @@ -359,7 +359,7 @@ public class PDAStack extends AbstractDsfService implements IStack { PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Unknown context type"); } } - + @DsfServiceEventHandler public void eventDispatched(IResumedDMEvent e) { // Mark the cache as not available, so that stack commands will diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java.html new file mode 100644 index 00000000000..efa44c42c84 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java.html @@ -0,0 +1,393 @@ + + + +PDAStack.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2008 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *******************************************************************************/
+ 11: package org.eclipse.dd.examples.pda.service;
+
+ 13: import java.util.Hashtable;
+
+ 15: import org.eclipse.cdt.core.IAddress;
+ 16: import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+ 17: import org.eclipse.dd.dsf.concurrent.Immutable;
+ 18: import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+ 19: import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
+ 20: import org.eclipse.dd.dsf.datamodel.DMContexts;
+ 21: import org.eclipse.dd.dsf.datamodel.IDMContext;
+ 22: import org.eclipse.dd.dsf.debug.service.IRunControl;
+ 23: import org.eclipse.dd.dsf.debug.service.IStack;
+ 24: import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
+ 25: import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
+ 26: import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
+ 27: import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
+ 28: import org.eclipse.dd.dsf.debug.service.command.CommandCache;
+ 29: import org.eclipse.dd.dsf.service.AbstractDsfService;
+ 30: import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
+ 31: import org.eclipse.dd.dsf.service.DsfSession;
+ 32: import org.eclipse.dd.dsf.service.IDsfService;
+ 33: import org.eclipse.dd.examples.pda.PDAPlugin;
+ 34: import org.eclipse.dd.examples.pda.service.commands.PDAFrame;
+ 35: import org.eclipse.dd.examples.pda.service.commands.PDAStackCommand;
+ 36: import org.eclipse.dd.examples.pda.service.commands.PDAStackCommandResult;
+ 37: import org.osgi.framework.BundleContext;
+
+ 39: /**
+ 40:  * Service for retrieving PDA debugger stack data. 
+ 41:  * <p>
+ 42:  * This service depends on the {@link PDACommandControl} service and the 
+ 43:  * {@link IRunControl} service.  These services must be initialized before 
+ 44:  * this service is initialized.
+ 45:  * </p>
+ 46:  */
+ 47: public class PDAStack extends AbstractDsfService implements IStack {
+
+ 49:     /**
+ 50:      * PDA stack frame contains only the stack frame level.  It is only 
+ 51:      * used as an index into the frame data returned by the PDA debugger.
+ 52:      */
+ 53:     @Immutable
+ 54:     private static class FrameDMContext extends AbstractDMContext implements IFrameDMContext {
+
+ 56:         final private int fLevel;
+
+ 58:         FrameDMContext(String sessionId, IExecutionDMContext execDmc, int level) {
+ 59:             super(sessionId, new IDMContext[] { execDmc });
+ 60:             fLevel = level;
+ 61:         }
+
+ 63:         public int getLevel() { return fLevel; }
+
+ 65:         @Override
+ 66:         public boolean equals(Object other) {
+ 67:             return super.baseEquals(other) && ((FrameDMContext)other).fLevel == fLevel;
+ 68:         }
+
+ 70:         @Override
+ 71:         public int hashCode() {
+ 72:             return super.baseHashCode() ^ fLevel;
+ 73:         }
+
+ 75:         @Override
+ 76:         public String toString() { 
+ 77:             return baseToString() + ".frame[" + fLevel + "]";  //$NON-NLS-1$ //$NON-NLS-2$
+ 78:         }
+ 79:     }
+
+ 81:     /**
+ 82:      * Frame data based on the PDAFrame object returned by the PDA debugger.
+ 83:      */
+ 84:     @Immutable
+ 85:     private static class FrameDMData implements IFrameDMData {
+
+ 87:         final private PDAFrame fFrame;
+
+ 89:         FrameDMData(PDAFrame frame) {
+ 90:             fFrame = frame;
+ 91:         }
+
+ 93:         public String getFile() {
+ 94:             return fFrame.fFilePath.lastSegment();
+ 95:         }
+
+ 97:         public String getFunction() {
+ 98:             return fFrame.fFunction;
+ 99:         }
+
+101:         public int getLine() {
+102:             return fFrame.fLine + 1;
+103:         }
+
+105:         public int getColumn() {
+106:             return 0;
+107:         }
+
+109:         public IAddress getAddress() {
+110:             return null;
+111:         }
+112:     }
+
+114:     /**
+115:      * Context representing a variable in a given stack frame.
+116:      */
+117:     @Immutable
+118:     private static class VariableDMContext extends AbstractDMContext implements IVariableDMContext {
+
+120:         final private String fVariable;
+
+122:         VariableDMContext(String sessionId, IFrameDMContext frameCtx, String variable) {
+123:             super(sessionId, new IDMContext[] { frameCtx });
+124:             fVariable = variable;
+125:         }
+
+127:         String getVariable() { return fVariable; }
+
+129:         @Override
+130:         public boolean equals(Object other) {
+131:             return super.baseEquals(other) && ((VariableDMContext)other).fVariable.equals(fVariable);
+132:         }
+
+134:         @Override
+135:         public int hashCode() {
+136:             return super.baseHashCode() + fVariable.hashCode();
+137:         }
+
+139:         @Override
+140:         public String toString() { 
+141:             return baseToString() + ".variable(" + fVariable + ")";  //$NON-NLS-1$ //$NON-NLS-2$
+142:         }
+143:     }
+
+145:     /**
+146:      * PDA variable data, only supports returning the variable name.
+147:      */
+148:     @Immutable
+149:     private static class VariableDMData implements IVariableDMData {
+
+151:         final private String fVariable;
+
+153:         VariableDMData(String variable) {
+154:             fVariable = variable;
+155:         }
+
+157:         public String getName() {
+158:             return fVariable;
+159:         }
+
+161:         public String getValue() {
+162:             return null;
+163:         }
+164:     }
+
+166:     // Services that this service depends on.
+167:     private PDACommandControl fCommandControl;
+168:     private IRunControl fRunControl;
+
+170:     // Command cache 
+171:     private CommandCache fCommandCache;
+
+173:     public PDAStack(DsfSession session) {
+174:         super(session);
+175:     }
+
+177:     @Override
+178:     protected BundleContext getBundleContext() {
+179:         return PDAPlugin.getBundleContext();
+180:     }
+
+182:     @Override
+183:     public void initialize(final RequestMonitor rm) {
+184:         super.initialize(
+185:             new RequestMonitor(getExecutor(), rm) { 
+186:                 @Override
+187:                 protected void handleOK() {
+188:                     doInitialize(rm);
+189:                 }});
+190:     }
+
+192:     private void doInitialize(final RequestMonitor rm) {
+193:         // Initialize service references that stack service depends on
+194:         fCommandControl = getServicesTracker().getService(PDACommandControl.class);
+195:         fRunControl = getServicesTracker().getService(IRunControl.class);
+
+197:         // Create the commands cache
+198:         fCommandCache = new CommandCache(fCommandControl);
+
+200:         // Register to listen for run control events, to clear cache accordingly.
+201:         getSession().addServiceEventListener(this, null);
+
+203:         // Register stack service with OSGi
+204:         register(new String[]{IStack.class.getName(), PDAStack.class.getName()}, new Hashtable<String,String>());
+
+206:         rm.done();
+207:     }
+
+209:     @Override
+210:     public void shutdown(final RequestMonitor rm) {
+211:         getSession().removeServiceEventListener(this);
+212:         fCommandCache.reset();
+213:         super.shutdown(rm);
+214:     }
+
+
+217:     public void getArguments(IFrameDMContext frameCtx, DataRequestMonitor<IVariableDMContext[]> rm) {
+218:         PDAPlugin.failRequest(rm, IDsfService.NOT_SUPPORTED, "PDA debugger does not support function arguments.");
+219:     }
+
+221:     public void getFrameData(final IFrameDMContext frameCtx, final DataRequestMonitor<IFrameDMData> rm) {
+222:         // Execute the PDA stack command, or retrieve the result from cache if already available.
+223:         fCommandCache.execute(
+224:             new PDAStackCommand(fCommandControl.getProgramDMContext()),
+225:             new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
+226:                 @Override
+227:                 protected void handleOK() {
+228:                     // PDAFrame array is ordered highest to lowest.  We need to 
+229:                     // calculate the index based on frame level.
+230:                     int frameId = getData().fFrames.length - frameCtx.getLevel() - 1;
+231:                     if (frameId < 0) {
+232:                         PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx);
+233:                         return;
+234:                     }
+
+236:                     // Create the frame data object based on the corresponding PDAFrame
+237:                     rm.setData(new FrameDMData(getData().fFrames[frameId]));
+238:                     rm.done();
+239:                 }
+240:             });
+241:     }
+
+
+244:     public void getFrames(IDMContext context, final DataRequestMonitor<IFrameDMContext[]> rm) {
+245:         // Can only create stack frames for an execution context as a parent, 
+246:         // however the argument context is a generic context type, so it could 
+247:         // be an execution context, a frame, a variable, etc. Search the 
+248:         // hierarchy of the argument context to find the execution one.
+249:         final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
+250:         if (execCtx == null) {
+251:             PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context);
+252:             return;
+253:         }
+
+255:         // Execute the stack command and create the corresponding frame contexts.
+256:         fCommandCache.execute(
+257:             new PDAStackCommand(fCommandControl.getProgramDMContext()),
+258:             new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
+259:                 @Override
+260:                 protected void handleOK() {
+261:                     IFrameDMContext[] frameCtxs = new IFrameDMContext[getData().fFrames.length];
+262:                     for (int i = 0; i < getData().fFrames.length; i++) {
+263:                         frameCtxs[i] = new FrameDMContext(getSession().getId(), execCtx, i);
+264:                     }
+265:                     rm.setData(frameCtxs);
+266:                     rm.done();
+267:                 }
+268:             });
+269:     }
+
+271:     public void getLocals(final IFrameDMContext frameCtx, final DataRequestMonitor<IVariableDMContext[]> rm) {
+272:         // Execute the stack command again.
+273:         fCommandCache.execute(
+274:             new PDAStackCommand(fCommandControl.getProgramDMContext()),
+275:             new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
+276:                 @Override
+277:                 protected void handleOK() {
+278:                     // Find the correct PDAFrame
+279:                     int frameId = getData().fFrames.length - frameCtx.getLevel() - 1;
+280:                     if (frameId < 0) {
+281:                         PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid frame level " + frameCtx);
+282:                         return;
+283:                     }
+284:                     PDAFrame pdaFrame = getData().fFrames[frameId];
+
+286:                     // Create variable contexts for all variables in frame.
+287:                     IVariableDMContext[] variableCtxs = new IVariableDMContext[pdaFrame.fVariables.length];
+288:                     for (int i = 0; i < pdaFrame.fVariables.length; i++) {
+289:                         variableCtxs[i] = new VariableDMContext(getSession().getId(), frameCtx, pdaFrame.fVariables[i]);
+290:                     }
+291:                     rm.setData(variableCtxs);
+292:                     rm.done();
+293:                 }
+294:             });
+
+296:     }
+
+298:     public void getStackDepth(IDMContext context, int maxDepth, final DataRequestMonitor<Integer> rm) {
+299:         // Execute stack command and return the data's size.
+300:         fCommandCache.execute(
+301:             new PDAStackCommand(fCommandControl.getProgramDMContext()),
+302:             new DataRequestMonitor<PDAStackCommandResult>(getExecutor(), rm) {
+303:                 @Override
+304:                 protected void handleOK() {
+305:                     rm.setData(getData().fFrames.length);
+306:                     rm.done();
+307:                 }
+308:             });
+309:     }
+
+311:     public void getTopFrame(IDMContext context, final DataRequestMonitor<IFrameDMContext> rm) {
+312:         // Can only create stack frames for an execution context as a parent, 
+313:         // however the argument context is a generic context type, so it could 
+314:         // be an execution context, a frame, a variable, etc. Search the 
+315:         // hierarchy of the argument context to find the execution one.
+316:         final IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
+317:         if (execCtx == null) {
+318:             PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + context);
+319:             return;
+320:         }
+
+322:         // Since the frame context only contain the level, there's no need to 
+323:         // call the PDA debugger.  Simply create a context for level 0. 
+324:         rm.setData(new FrameDMContext(getSession().getId(), execCtx, 0));
+325:         rm.done();
+326:     }
+
+328:     public void getVariableData(IVariableDMContext variableCtx, DataRequestMonitor<IVariableDMData> rm) {
+329:         if ( !(variableCtx instanceof VariableDMContext) ) {
+330:             PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Invalid context " + variableCtx);
+331:             return;
+332:         }
+
+334:         // The variable data doen't contain a value.  So there's no need to 
+335:         // go to the back end to retrieve it.
+336:         String variable = ((VariableDMContext)variableCtx).getVariable();
+
+338:         rm.setData(new VariableDMData(variable));
+339:         rm.done();
+340:     }
+
+342:     public boolean isStackAvailable(IDMContext context) {
+343:         // Stack is available if the program is suspended or stepping.
+344:         IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
+345:         return execCtx != null && (fRunControl.isSuspended(execCtx) || (fRunControl.isStepping(execCtx)));
+346:     }
+
+348:     @SuppressWarnings("unchecked")
+349:     @Deprecated
+350:     public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
+351:         // The getModelData() is deprecated and clients are expected to switch
+352:         // to getExecutionData() and other data retrieve methods directly.
+353:         // However the UI cache still uses it for now.
+354:         if (dmc instanceof IFrameDMContext) {
+355:             getFrameData((IFrameDMContext)dmc, (DataRequestMonitor<IFrameDMData>)rm);
+356:         } else if (dmc instanceof IVariableDMContext) {
+357:             getVariableData((IVariableDMContext)dmc, (DataRequestMonitor<IVariableDMData>)rm);
+358:         } else {
+359:             PDAPlugin.failRequest(rm, IDsfService.INVALID_HANDLE, "Unknown context type");
+360:         }
+361:     }
+
+363:     @DsfServiceEventHandler 
+364:     public void eventDispatched(IResumedDMEvent e) {
+365:         // Mark the cache as not available, so that stack commands will
+366:         // fail.  Also reset the cache unless it was a step command.
+367:         fCommandCache.setTargetAvailable(false);
+368:         if (!e.getReason().equals(StateChangeReason.STEP)) {
+369:             fCommandCache.reset();
+370:         }
+371:     }    
+
+
+374:     @DsfServiceEventHandler 
+375:     public void eventDispatched(ISuspendedDMEvent e) {
+376:         // Enable sending commands to target and clear the cache.
+377:         fCommandCache.setTargetAvailable(true);
+378:         fCommandCache.reset();
+379:     }
+380: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/AbstractPDACommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/AbstractPDACommand.java index bd75d996c63..fd73851120c 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/AbstractPDACommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/AbstractPDACommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * a context. Since the PDA debugger protocol is stateless, the context is only * needed to satisfy the ICommand interface. */ +@Immutable abstract public class AbstractPDACommand implements ICommand { final private IDMContext fContext; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAClearBreakpointCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAClearBreakpointCommand.java index b0873d3254d..35b9717e3f9 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAClearBreakpointCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAClearBreakpointCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -21,6 +22,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * */ +@Immutable public class PDAClearBreakpointCommand extends AbstractPDACommand { public PDAClearBreakpointCommand(PDAProgramDMContext context, int line) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDACommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDACommandResult.java index 053f2e99796..16cfe82fd3d 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDACommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDACommandResult.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.dsf.debug.service.command.ICommand; import org.eclipse.dd.dsf.debug.service.command.ICommandResult; @@ -19,6 +20,7 @@ import org.eclipse.dd.dsf.debug.service.command.ICommandResult; * PDA response. Sub-classes may override to optionally parse the response text * and return higher-level objects. */ +@Immutable public class PDACommandResult implements ICommandResult { final public String fResponseText; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java index fab0f679ba0..2fa76f1bed4 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,14 +21,15 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: {value 1}|{value 2}|{value 3}|...| * */ -public class PDADataCommand extends AbstractPDACommand { +@Immutable +public class PDADataCommand extends AbstractPDACommand { public PDADataCommand(PDAProgramDMContext context) { super(context, "data"); } @Override - public PDACommandResult createResult(String resultText) { - return new PDACommandResult(resultText); + public PDADataCommandResult createResult(String resultText) { + return new PDADataCommandResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java.html new file mode 100644 index 00000000000..311cbceb6b0 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java.html @@ -0,0 +1,46 @@ + + + +PDADataCommand.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2008 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *******************************************************************************/
+ 11: package org.eclipse.dd.examples.pda.service.commands;
+
+ 13: import org.eclipse.dd.examples.pda.service.PDAProgramDMContext;
+
+ 15: /**
+ 16:  * Retrieves data stack information 
+ 17:  * 
+ 18:  * <pre>
+ 19:  *    C: data
+ 20:  *    R: {value 1}|{value 2}|{value 3}|...|
+ 21:  * </pre>
+ 22:  */
+ 23: public class PDADataCommand extends AbstractPDACommand<PDADataCommandResult> {
+
+ 25:     public PDADataCommand(PDAProgramDMContext context) {
+ 26:         super(context, "data");
+ 27:     }
+ 28:     
+ 29:     @Override
+ 30:     public PDADataCommandResult createResult(String resultText) {
+ 31:         return new PDADataCommandResult(resultText);
+ 32:     }
+ 33: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java index e31b1c8ae58..aff431a7ec6 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java @@ -14,10 +14,13 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; +import org.eclipse.dd.dsf.concurrent.Immutable; + /** * @see PDADataCommand */ +@Immutable public class PDADataCommandResult extends PDACommandResult { final public String[] fValues; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java.html new file mode 100644 index 00000000000..b5f3ae2cb46 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java.html @@ -0,0 +1,55 @@ + + + +PDADataCommandResult.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2008 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *******************************************************************************/
+ 11: package org.eclipse.dd.examples.pda.service.commands;
+
+ 13: import java.util.ArrayList;
+ 14: import java.util.List;
+ 15: import java.util.StringTokenizer;
+
+
+ 18: /**
+ 19:  * @see PDADataCommand
+ 20:  */
+ 21: public class PDADataCommandResult extends PDACommandResult {
+ 22:     
+ 23:     final public String[] fValues;
+ 24:     
+ 25:     PDADataCommandResult(String response) {
+ 26:         super(response);
+ 27:         StringTokenizer st = new StringTokenizer(response, "|");
+ 28:         List<String> valuesList = new ArrayList<String>();
+ 29:         
+ 30:         while (st.hasMoreTokens()) {
+ 31:             String token = st.nextToken();
+ 32:             if (token.length() != 0) {
+ 33:                 valuesList.add(st.nextToken());
+ 34:             }
+ 35:         }
+ 36:         
+ 37:         fValues = new String[valuesList.size()];
+ 38:         for (int i = 0; i < valuesList.size(); i++) {
+ 39:             fValues[i] = valuesList.get(i);
+ 40:         }
+ 41:     }
+ 42: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADropFrameCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADropFrameCommand.java index 1a1f4cc8f92..d68c173dd52 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADropFrameCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADropFrameCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -23,6 +24,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * */ +@Immutable public class PDADropFrameCommand extends AbstractPDACommand { public PDADropFrameCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEvalCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEvalCommand.java index 082362e7415..10a4d707132 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEvalCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEvalCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -25,6 +26,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * * Where event_name could be unimpinstr or nosuchlabel. */ +@Immutable public class PDAEvalCommand extends AbstractPDACommand { public PDAEvalCommand(PDAProgramDMContext context, String operation) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEventStopCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEventStopCommand.java index 653f2aa945a..d247f829c4b 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEventStopCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAEventStopCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -24,6 +25,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * * Where event_name could be unimpinstr or nosuchlabel. */ +@Immutable public class PDAEventStopCommand extends AbstractPDACommand { public enum Event { UNIMPINSTR, NOSUCHLABEL }; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAExitCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAExitCommand.java index 0514aa675f5..7b7222b7b27 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAExitCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAExitCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: ok * */ +@Immutable public class PDAExitCommand extends AbstractPDACommand { public PDAExitCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAFrame.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAFrame.java index ab2b2c5612a..5ef52dc542a 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAFrame.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAFrame.java @@ -16,12 +16,14 @@ import java.util.StringTokenizer; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; +import org.eclipse.dd.dsf.concurrent.Immutable; /** * Object representing a frame in the stack command results. * * @see PDAStackCommand */ +@Immutable public class PDAFrame { final public IPath fFilePath; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPopDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPopDataCommand.java index 952e53cd17c..de6649b785b 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPopDataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPopDataCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: ok * */ +@Immutable public class PDAPopDataCommand extends AbstractPDACommand { public PDAPopDataCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPushDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPushDataCommand.java index 7226c765518..d201e9b05ec 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPushDataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAPushDataCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: ok * */ +@Immutable public class PDAPushDataCommand extends AbstractPDACommand { public PDAPushDataCommand(PDAProgramDMContext context, int value) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java index 35b83c35a13..6a7e46f1a29 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -21,6 +22,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * E: resumed client * */ +@Immutable public class PDAResumeCommand extends AbstractPDACommand { public PDAResumeCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java.html b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java.html new file mode 100644 index 00000000000..ae563692a2f --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAResumeCommand.java.html @@ -0,0 +1,47 @@ + + + +PDAResumeCommand.java + + + + + +
  1: /*******************************************************************************
+  2:  * Copyright (c) 2008 Wind River Systems and others.
+  3:  * All rights reserved. This program and the accompanying materials
+  4:  * are made available under the terms of the Eclipse Public License v1.0
+  5:  * which accompanies this distribution, and is available at
+  6:  * http://www.eclipse.org/legal/epl-v10.html
+  7:  * 
+  8:  * Contributors:
+  9:  *     Wind River Systems - initial API and implementation
+ 10:  *******************************************************************************/
+ 11: package org.eclipse.dd.examples.pda.service.commands;
+
+ 13: import org.eclipse.dd.examples.pda.service.PDAProgramDMContext;
+
+ 15: /**
+ 16:  * Resumes the execution  
+ 17:  * 
+ 18:  * <pre>
+ 19:  *    C: resume
+ 20:  *    R: ok
+ 21:  *    E: resumed client
+ 22:  * </pre>
+ 23:  */
+ 24: public class PDAResumeCommand extends AbstractPDACommand<PDACommandResult> {
+
+ 26:     public PDAResumeCommand(PDAProgramDMContext context) {
+ 27:         super(context, "resume");
+ 28:     }
+ 29:     
+ 30:     @Override
+ 31:     public PDACommandResult createResult(String resultText) {
+ 32:         return new PDACommandResult(resultText);
+ 33:     }
+ 34: }
+
+ + + diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetBreakpointCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetBreakpointCommand.java index 7dd14c6456a..4bfd3370df6 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetBreakpointCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetBreakpointCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -23,6 +24,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * E: suspended breakpoint line_number * */ +@Immutable public class PDASetBreakpointCommand extends AbstractPDACommand { public PDASetBreakpointCommand(PDAProgramDMContext context, int line) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetDataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetDataCommand.java index b66772f8688..706700c8f7f 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetDataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetDataCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: ok * */ +@Immutable public class PDASetDataCommand extends AbstractPDACommand { public PDASetDataCommand(PDAProgramDMContext context, int index, String value) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetVarCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetVarCommand.java index 5fcf7d77b49..f18340e20d4 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetVarCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASetVarCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: ok * */ +@Immutable public class PDASetVarCommand extends AbstractPDACommand { public PDASetVarCommand(PDAProgramDMContext context, int frame, String variable, String value) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommand.java index cd26fa07ff5..aef4d4aa795 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: {file}|{line}|{function}|{var_1}|{var_2}|...#{file}|{line}|{function}|{var_1}|{var_2}|...#... * */ +@Immutable public class PDAStackCommand extends AbstractPDACommand { public PDAStackCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommandResult.java index 5cc1bf1fc71..7bd9877cd19 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStackCommandResult.java @@ -14,10 +14,13 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; +import org.eclipse.dd.dsf.concurrent.Immutable; + /** * @see PDAStackCommand */ +@Immutable public class PDAStackCommandResult extends PDACommandResult { /** diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepCommand.java index a50713acc8b..ce50cf5c228 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepCommand.java @@ -10,10 +10,11 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** - * Executes next instruciton + * Executes next instruction * *
  *    C: step
@@ -22,6 +23,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext;
  *    E: suspended step
  * 
*/ +@Immutable public class PDAStepCommand extends AbstractPDACommand { public PDAStepCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepReturnCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepReturnCommand.java index 8ba0dedfb3b..8b9d7c8a675 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepReturnCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAStepReturnCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -22,6 +23,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * E: suspended step * */ +@Immutable public class PDAStepReturnCommand extends AbstractPDACommand { public PDAStepReturnCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASuspendCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASuspendCommand.java index f1c7e548b85..5abde431178 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASuspendCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDASuspendCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -21,6 +22,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * E: suspended client * */ +@Immutable public class PDASuspendCommand extends AbstractPDACommand { public PDASuspendCommand(PDAProgramDMContext context) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAVarCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAVarCommand.java index 745fa86a491..cc57a527161 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAVarCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAVarCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -20,6 +21,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * R: {variable_value} * */ +@Immutable public class PDAVarCommand extends AbstractPDACommand { public PDAVarCommand(PDAProgramDMContext context, int frameId, String name) { diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAWatchCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAWatchCommand.java index 91d54e942a0..f6bf1982545 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAWatchCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAWatchCommand.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.dd.examples.pda.service.commands; +import org.eclipse.dd.dsf.concurrent.Immutable; import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; /** @@ -23,6 +24,7 @@ import org.eclipse.dd.examples.pda.service.PDAProgramDMContext; * E: suspended watch {watch_operation} {function}::{variable_name} * */ +@Immutable public class PDAWatchCommand extends AbstractPDACommand { public enum WatchOperation { READ, WRITE, BOTH, NONE }; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourceLookupDirector.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourceLookupDirector.java index d22968d6be9..1c7ec8b518f 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourceLookupDirector.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/sourcelookup/PDASourceLookupDirector.java @@ -19,7 +19,7 @@ import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector; */ public class PDASourceLookupDirector extends AbstractSourceLookupDirector { public void initializeParticipants() { - // No need to add participants here, the surce display adapter will + // No need to add participants here, the source display adapter will // add the participant with the correct session ID. } }