diff options
Diffstat (limited to 'plugins')
52 files changed, 1765 insertions, 2596 deletions
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java index 3a062ec04..8a9b280b6 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java @@ -17,6 +17,7 @@ import java.util.Map; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IToken; +import org.eclipse.tm.tcf.util.TCFDataCache; /** * TCFChildren is a concrete type of TCF data cache that is used to cache a list of children. diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java index 343edfb29..2a1b609d9 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java @@ -18,6 +18,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.IMemory; import org.eclipse.tm.tcf.services.IRunControl; +import org.eclipse.tm.tcf.util.TCFDataCache; /** diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java index c6281fc05..f48adea2b 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java @@ -303,8 +303,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider, if (run != null) run.addListener(run_listener); IRegisters reg = launch.getService(IRegisters.class); if (reg != null) reg.addListener(reg_listener); - launch_node.makeModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); - fireModelChanged(); + launchChanged(); } void onDisconnected() { @@ -313,10 +312,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider, for (int i = 0; i < a.length; i++) { if (!a[i].isDisposed()) a[i].dispose(); } - if (launch_node != null) { - launch_node.makeModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); - fireModelChanged(); - } + launchChanged(); } void onProxyInstalled(final TCFModelProxy p) { diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java index 861e91057..3895affa7 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java @@ -151,6 +151,7 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo final void update(final IChildrenCountUpdate result) { new TCFRunnable(model.getDisplay(), result) { public void run() { + if (result.isCanceled()) return; IChannel channel = model.getLaunch().getChannel(); if (!disposed && channel.getState() == IChannel.STATE_OPEN) { if (!validateNode(this)) return; @@ -172,6 +173,7 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo final void update(final IChildrenUpdate result) { new TCFRunnable(model.getDisplay(), result) { public void run() { + if (result.isCanceled()) return; IChannel channel = model.getLaunch().getChannel(); if (!disposed && channel.getState() == IChannel.STATE_OPEN) { if (!validateNode(this)) return; @@ -190,6 +192,7 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo final void update(final IHasChildrenUpdate result) { new TCFRunnable(model.getDisplay(), result) { public void run() { + if (result.isCanceled()) return; IChannel channel = model.getLaunch().getChannel(); if (!disposed && channel.getState() == IChannel.STATE_OPEN) { if (!validateNode(this)) return; @@ -211,6 +214,7 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo final void update(final ILabelUpdate result) { new TCFRunnable(model.getDisplay(), result) { public void run() { + if (result.isCanceled()) return; IChannel channel = model.getLaunch().getChannel(); if (!disposed && channel.getState() == IChannel.STATE_OPEN) { if (!validateNode(this)) return; diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java index 6303b1558..119665057 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java @@ -28,6 +28,7 @@ import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.protocol.Protocol; import org.eclipse.tm.tcf.services.IMemory; import org.eclipse.tm.tcf.services.IRunControl; +import org.eclipse.tm.tcf.util.TCFDataCache; @SuppressWarnings("serial") @@ -218,7 +219,6 @@ public class TCFNodeExecContext extends TCFNode { @Override protected void getData(IChildrenUpdate result) { - int offset = 0; TCFNode[] arr = null; IRunControl.RunControlContext ctx = run_context.getData(); if (ctx != null && ctx.hasState()) { @@ -233,8 +233,11 @@ public class TCFNodeExecContext extends TCFNode { arr = children_exec.toArray(); } Arrays.sort(arr); + int offset = 0; + int r_offset = result.getOffset(); + int r_length = result.getLength(); for (TCFNode n : arr) { - if (offset >= result.getOffset() && offset < result.getOffset() + result.getLength()) { + if (offset >= r_offset && offset < r_offset + r_length) { result.setChild(n, offset); } offset++; diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java index 6b767821d..84cf9df0b 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java @@ -49,11 +49,13 @@ public class TCFNodeLaunch extends TCFNode { @Override protected void getData(IChildrenUpdate result) { - int offset = 0; TCFNode[] arr = children.toArray(); Arrays.sort(arr); + int offset = 0; + int r_offset = result.getOffset(); + int r_length = result.getLength(); for (TCFNode n : arr) { - if (offset >= result.getOffset() && offset < result.getOffset() + result.getLength()) { + if (offset >= r_offset && offset < r_offset + r_length) { result.setChild(n, offset); } offset++; diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java index 50a3e44e5..6fc559085 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java @@ -22,6 +22,7 @@ import org.eclipse.tm.internal.tcf.debug.ui.ImageCache; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.IRegisters; +import org.eclipse.tm.tcf.util.TCFDataCache; //TODO: hierarchical registers diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java index 71c037ed2..84efbc5d6 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java @@ -30,8 +30,8 @@ import org.eclipse.tm.tcf.services.IMemory; import org.eclipse.tm.tcf.services.IRunControl; import org.eclipse.tm.tcf.services.IStackTrace; import org.eclipse.tm.tcf.services.ILineNumbers.CodeArea; +import org.eclipse.tm.tcf.util.TCFDataCache; -@SuppressWarnings("serial") public class TCFNodeStackFrame extends TCFNode { private int frame_no; @@ -56,7 +56,7 @@ public class TCFNodeStackFrame extends TCFNode { IStackTrace st = model.getLaunch().getService(IStackTrace.class); command = st.getContext(new String[]{ id }, new IStackTrace.DoneGetContext() { public void doneGetContext(IToken token, Exception error, IStackTrace.StackTraceContext[] context) { - set(token, error, context[0]); + set(token, error, context == null || context.length == 0 ? null : context[0]); } }); return false; @@ -190,7 +190,6 @@ public class TCFNodeStackFrame extends TCFNode { @Override protected void getData(IChildrenUpdate result) { - int offset = 0; TCFNode[] arr = null; if (IDebugUIConstants.ID_REGISTER_VIEW.equals(result.getPresentationContext().getId())) { arr = children_regs.toArray(); @@ -200,8 +199,11 @@ public class TCFNodeStackFrame extends TCFNode { } if (arr != null) { Arrays.sort(arr); + int offset = 0; + int r_offset = result.getOffset(); + int r_length = result.getLength(); for (TCFNode n : arr) { - if (offset >= result.getOffset() && offset < result.getOffset() + result.getLength()) { + if (offset >= r_offset && offset < r_offset + r_length) { result.setChild(n, offset); } offset++; diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java index 7993267f4..00ae04f60 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java @@ -324,11 +324,11 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana m.put(IMarker.MESSAGE, "Breakpoint: " + msg); Number line = (Number)p.get(IBreakpoints.PROP_LINE); if (line != null) { - m.put(IMarker.LINE_NUMBER, Integer.toString(line.intValue() + 1)); + m.put(IMarker.LINE_NUMBER, new Integer(line.intValue() + 1)); Number column = (Number)p.get(IBreakpoints.PROP_COLUMN); if (column != null) { - m.put(IMarker.CHAR_START, column.toString()); - m.put(IMarker.CHAR_END, Integer.toString(column.intValue() + 1)); + m.put(IMarker.CHAR_START, new Integer(column.intValue())); + m.put(IMarker.CHAR_END, new Integer(column.intValue() + 1)); } } return m; @@ -350,13 +350,11 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana } if (file != null) { m.put(IBreakpoints.PROP_FILE, file); - String line = (String)p.get(IMarker.LINE_NUMBER); + Integer line = (Integer)p.get(IMarker.LINE_NUMBER); if (line != null) { - m.put(IBreakpoints.PROP_LINE, new Integer(Integer.parseInt(line) - 1)); - String column = (String)p.get(IMarker.CHAR_START); - if (column != null) { - m.put(IBreakpoints.PROP_COLUMN, new Integer(column)); - } + m.put(IBreakpoints.PROP_LINE, new Integer(line.intValue() - 1)); + Integer column = (Integer)p.get(IMarker.CHAR_START); + if (column != null) m.put(IBreakpoints.PROP_COLUMN, column); } } return m; diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java index 6bacd0c49..7bee2287c 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java @@ -60,6 +60,8 @@ public class TCFLaunch extends Launch { private TCFBreakpointsStatus breakpoints_status; private String mode; private boolean connecting; + private boolean disconnected; + private boolean shutdown; private ProcessContext process; public TCFLaunch(ILaunchConfiguration launchConfiguration, String mode) { @@ -67,6 +69,7 @@ public class TCFLaunch extends Launch { } private void onConnected() { + // The method is called when TCF channel is successfully connected. try { final Runnable done = new Runnable() { public void run() { @@ -93,6 +96,58 @@ public class TCFLaunch extends Launch { } } + private void onDisconnected(Throwable error) { + // The method is called when TCF channel is closed. + assert !disconnected; + assert !shutdown; + this.error = error; + breakpoints_status = null; + connecting = false; + disconnected = true; + for (Iterator<Listener> i = listeners.iterator(); i.hasNext();) { + i.next().onDisconnected(this); + } + if (error != null) setError(error); + else fireChanged(); + runShutdownSequence(new Runnable() { + public void run() { + shutdown = true; + if (DebugPlugin.getDefault() != null) fireTerminate(); + } + }); + } + + private String[] toArgsArray(String file, String cmd) { + // Create arguments list from a command line. + int i = 0; + int l = cmd.length(); + List<String> arr = new ArrayList<String>(); + arr.add(file); + for (;;) { + while (i < l && cmd.charAt(i) == ' ') i++; + if (i >= l) break; + String s = null; + if (cmd.charAt(i) == '"') { + i++; + StringBuffer bf = new StringBuffer(); + while (i < l) { + char ch = cmd.charAt(i++); + if (ch == '"') break; + if (ch == '\\' && i < l) ch = cmd.charAt(i++); + bf.append(ch); + } + s = bf.toString(); + } + else { + int i0 = i; + while (i < l && cmd.charAt(i) != ' ') i++; + s = cmd.substring(i0, i); + } + arr.add(s); + } + return arr.toArray(new String[arr.size()]); + } + @SuppressWarnings("unchecked") protected void runLaunchSequence(final Runnable done) { try { @@ -138,48 +193,10 @@ public class TCFLaunch extends Launch { } } - private String[] toArgsArray(String file, String cmd) { - int i = 0; - int l = cmd.length(); - List<String> arr = new ArrayList<String>(); - arr.add(file); - for (;;) { - while (i < l && cmd.charAt(i) == ' ') i++; - if (i >= l) break; - String s = null; - if (cmd.charAt(i) == '"') { - i++; - StringBuffer bf = new StringBuffer(); - while (i < l) { - char ch = cmd.charAt(i++); - if (ch == '"') break; - if (ch == '\\' && i < l) ch = cmd.charAt(i++); - bf.append(ch); - } - s = bf.toString(); - } - else { - int i0 = i; - while (i < l && cmd.charAt(i) != ' ') i++; - s = cmd.substring(i0, i); - } - arr.add(s); - } - return arr.toArray(new String[arr.size()]); + protected void runShutdownSequence(final Runnable done) { + done.run(); } - private void onDisconnected(Throwable error) { - this.error = error; - breakpoints_status = null; - connecting = false; - for (Iterator<Listener> i = listeners.iterator(); i.hasNext();) { - i.next().onDisconnected(this); - } - if (error != null) setError(error); - else fireChanged(); - if (DebugPlugin.getDefault() != null) fireTerminate(); - } - /*--------------------------------------------------------------------------------------------*/ public Throwable getError() { diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/plugin.xml b/plugins/org.eclipse.tm.tcf.dsf.ui/plugin.xml index 1f4a3c7a1..d43055aba 100644 --- a/plugins/org.eclipse.tm.tcf.dsf.ui/plugin.xml +++ b/plugins/org.eclipse.tm.tcf.dsf.ui/plugin.xml @@ -7,7 +7,7 @@ <extension point="org.eclipse.debug.ui.launchConfigurationTabGroups"> <launchConfigurationTabGroup type="org.eclipse.tm.tcf.dsf.LaunchConfigurationType" - class="org.eclipse.tm.internal.tcf.dsf.ui.LaunchDialogTabGroup" + class="org.eclipse.tm.internal.tcf.dsf.ui.launch.LaunchDialogTabGroup" id="org.eclipse.dd.dsf.mi.launch.localRunLaunchTabGroup"> </launchConfigurationTabGroup> </extension> diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/Activator.java b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/Activator.java index 03355c9de..9565d7ffe 100644 --- a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/Activator.java +++ b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/Activator.java @@ -23,7 +23,7 @@ public class Activator extends AbstractUIPlugin { // The shared instance private static Activator plugin; - + /** * The constructor */ diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/AdapterFactory.java b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/AdapterFactory.java index 30f513bd3..b4407ab26 100644 --- a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/AdapterFactory.java +++ b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/AdapterFactory.java @@ -21,9 +21,9 @@ import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfStepReturnCommand; import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand; -import org.eclipse.dd.dsf.debug.ui.actions.DsfTerminateCommand; -import org.eclipse.dd.dsf.debug.ui.sourcelookup.MISourceDisplayAdapter; +import org.eclipse.dd.dsf.debug.ui.sourcelookup.DsfSourceDisplayAdapter; import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.concurrent.DisplayDsfExecutor; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchesListener2; @@ -39,8 +39,12 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentati import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; import org.eclipse.debug.ui.sourcelookup.ISourceDisplay; +import org.eclipse.swt.widgets.Display; import org.eclipse.tm.internal.tcf.debug.model.ITCFConstants; import org.eclipse.tm.internal.tcf.dsf.launch.TCFDSFLaunch; +import org.eclipse.tm.internal.tcf.dsf.ui.actions.TcfTerminateCommand; +import org.eclipse.tm.internal.tcf.dsf.ui.viewmodel.ViewModelAdapter; +import org.eclipse.tm.tcf.protocol.Protocol; @SuppressWarnings("restriction") @@ -51,13 +55,13 @@ public class AdapterFactory implements IAdapterFactory, DsfSession.SessionEndedL private final DsfSession session; final ViewModelAdapter view_model_adapter; - final MISourceDisplayAdapter source_display_adapter; + final DsfSourceDisplayAdapter source_display_adapter; final DsfStepIntoCommand step_into_command; final DsfStepOverCommand step_over_command; final DsfStepReturnCommand step_return_command; final DsfSuspendCommand suspend_command; final DsfResumeCommand resume_command; - final DsfTerminateCommand terminate_command; + final TcfTerminateCommand terminate_command; final IDebugModelProvider debug_model_provider; final TCFDSFLaunch lunch; //final BreakpointCommand breakpoint_command; @@ -69,7 +73,8 @@ public class AdapterFactory implements IAdapterFactory, DsfSession.SessionEndedL view_model_adapter = new ViewModelAdapter(session, launch); if (launch.getSourceLocator() instanceof ISourceLookupDirector) { - source_display_adapter = new MISourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); + source_display_adapter = new DsfSourceDisplayAdapter(session, + (ISourceLookupDirector)launch.getSourceLocator()); } else { source_display_adapter = null; @@ -81,7 +86,7 @@ public class AdapterFactory implements IAdapterFactory, DsfSession.SessionEndedL step_return_command = new DsfStepReturnCommand(session); suspend_command = new DsfSuspendCommand(session); resume_command = new DsfResumeCommand(session); - terminate_command = new DsfTerminateCommand(session); + terminate_command = new TcfTerminateCommand(session); //breakpoint_command = new BreakpointCommand(); //memory_retrieval = new DsfMemoryBlockRetrieval(ITCFConstants.ID_TCF_DEBUG_MODEL, ); session.registerModelAdapter(IStepIntoHandler.class, step_into_command); @@ -131,23 +136,40 @@ public class AdapterFactory implements IAdapterFactory, DsfSession.SessionEndedL } } - @SuppressWarnings({ "unchecked", "restriction" }) - private final Class[] adapter_list = { + private static final Class<?>[] adapter_list = { IElementContentProvider.class, IColumnPresentationFactory.class, IModelProxyFactory.class, ITerminateHandler.class }; - private Map<String,SessionAdapterSet> session_adapter_set_map = + private static final Map<String,SessionAdapterSet> session_adapter_set_map = Collections.synchronizedMap(new HashMap<String,SessionAdapterSet>()); public AdapterFactory() { + assert session_adapter_set_map.isEmpty(); DsfSession.addSessionEndedListener(this); DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); + final Display display = Display.getDefault(); + display.asyncExec(new Runnable() { + public void run() { + final DisplayDsfExecutor executer = DisplayDsfExecutor.getDisplayDsfExecutor(display); + Protocol.invokeLater(new Runnable() { + public void run() { + Protocol.addCongestionMonitor(new Protocol.CongestionMonitor() { + public int getCongestionLevel() { + int level = executer.getQueue().size() / 4 - 100; + if (level > 100) level = 100; + return level; + } + }); + } + }); + } + }); } - @SuppressWarnings({ "restriction", "unchecked" }) + @SuppressWarnings("unchecked") public Object getAdapter(Object adaptableObject, Class adapterType) { if (!(adaptableObject instanceof TCFDSFLaunch)) return null; @@ -197,11 +219,10 @@ public class AdapterFactory implements IAdapterFactory, DsfSession.SessionEndedL // Dispose the set of adapters for a launch only after the launch is removed. for (ILaunch launch : launches) { if (launch instanceof TCFDSFLaunch) { - DsfSession session = ((TCFDSFLaunch)launch).getSession(); + String id = ((TCFDSFLaunch)launch).getSession().getId(); synchronized (session_adapter_set_map) { - if (session_adapter_set_map.containsKey(session.getId())) { - session_adapter_set_map.get(session.getId()).dispose(); - session_adapter_set_map.remove(session); + if (session_adapter_set_map.containsKey(id)) { + session_adapter_set_map.remove(id).dispose(); } } } diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/ContainerLayoutNode.java b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/ContainerLayoutNode.java deleted file mode 100644 index 42c7a45f6..000000000 --- a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/ContainerLayoutNode.java +++ /dev/null @@ -1,159 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 Ericsson and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Ericsson - Initial API and implementation - * Wind River Systems - reused for TCF connection type - *******************************************************************************/ - -package org.eclipse.tm.internal.tcf.dsf.ui; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; -import org.eclipse.dd.dsf.debug.service.INativeProcesses; -import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.service.INativeProcesses.IProcessDMData; -import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl.IStartedDMEvent; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; -import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.ui.DebugUITools; -import org.eclipse.debug.ui.IDebugUIConstants; -import org.eclipse.tm.internal.tcf.debug.model.ITCFConstants; -import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFRunControl; - - -@SuppressWarnings("restriction") -public class ContainerLayoutNode extends AbstractDMVMLayoutNode{ - - class ContainerVMContext extends DMVMContext { - DsfMemoryBlockRetrieval retrieval; - - public ContainerVMContext(IDMContext dmc) { - super(dmc); - try { - retrieval = new DsfMemoryBlockRetrieval(ITCFConstants.ID_TCF_DEBUG_MODEL, dmc); - } - catch (DebugException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - @SuppressWarnings("unchecked") - @Override - public Object getAdapter(Class adapter) { - if (adapter.isInstance(retrieval)) { - return retrieval; - } - return super.getAdapter(adapter); - } - } - - @Override - protected IVMContext createVMContext(IDMContext dmc) { - return new ContainerVMContext(dmc); - } - - public ContainerLayoutNode(AbstractVMProvider provider, DsfSession session) { - super(provider, session, IRunControl.IExecutionDMContext.class); - } - - @Override - protected void updateElementsInSessionThread(final IChildrenUpdate update) { - if (!checkService(IRunControl.class, null, update)) return; - final IContainerDMContext contDmc = findDmcInPath( - update.getElementPath().getParentPath(), IContainerDMContext.class); - - getServicesTracker().getService(TCFDSFRunControl.class).getContainerContexts(contDmc, - new DataRequestMonitor<IExecutionDMContext[]>(getSession().getExecutor(), null){ - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - handleFailedUpdate(update); - return; - } - fillUpdateWithVMCs(update, getData()); - update.done(); - } - }); - } - - @Override - // Labels are only updated for elements that are visible. - protected void updateLabelInSessionThread(ILabelUpdate[] updates) { - for (final ILabelUpdate update : updates) { - if (!checkService(IRunControl.class, null, update)) continue; - if (!checkService(INativeProcesses.class, null, update)) continue; - - final IContainerDMContext dmc = findDmcInPath(update.getElementPath(), IContainerDMContext.class); - - INativeProcesses processes = getServicesTracker().getService(INativeProcesses.class); - - String imageKey = null; - - if (getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) { - imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED; - } - else { - imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING; - } - update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); - - processes.getProcessData( - processes.getProcessForDebugContext(dmc), - new DataRequestMonitor<IProcessDMData>(getSession().getExecutor(), null) { - @SuppressWarnings("restriction") - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - update.done(); - return; - } - update.setLabel(getData().getName(), 0); - update.done(); - } - }); - } - } - - @Override - protected int getNodeDeltaFlagsForDMEvent(IDMEvent<?> e) { - if (e instanceof IStartedDMEvent || e instanceof IExitedDMEvent) { - return IModelDelta.CONTENT; - } - if (e instanceof IRunControl.IContainerResumedDMEvent || e instanceof IRunControl.IContainerSuspendedDMEvent) { - return IModelDelta.STATE; - } - return IModelDelta.NO_CHANGE; - } - - @Override - protected void buildDeltaForDMEvent(final IDMEvent<?> e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { - - if (e instanceof IRunControl.IContainerResumedDMEvent || e instanceof IRunControl.IContainerSuspendedDMEvent) { - parentDelta.addNode(new DMVMContext(e.getDMContext()), IModelDelta.STATE); - } - if (e instanceof IStartedDMEvent || e instanceof IExitedDMEvent) { - parentDelta.addFlags(IModelDelta.CONTENT); - //parentDelta.addNode(new DMVMContext(e.getDMContext()), IModelDelta.CONTENT); - } - super.buildDeltaForDMEvent(e, parentDelta, nodeOffset, requestMonitor); - } -} diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/LaunchVMProvider.java b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/LaunchVMProvider.java deleted file mode 100644 index b91a2c74c..000000000 --- a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/LaunchVMProvider.java +++ /dev/null @@ -1,162 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.tm.internal.tcf.dsf.ui; - -import java.util.concurrent.RejectedExecutionException; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StackFramesLayoutNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardLaunchRootLayoutNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardProcessLayoutNode; -import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardLaunchRootLayoutNode.LaunchesEvent; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; -import org.eclipse.debug.core.DebugEvent; -import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.debug.core.IDebugEventSetListener; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.ILaunchesListener2; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; - - -@SuppressWarnings("restriction") -public class LaunchVMProvider extends AbstractDMVMProvider -implements IDebugEventSetListener, ILaunchesListener2 { - - @ThreadSafe - public LaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, - DsfSession session, ILaunch launch) - { - super(adapter, presentationContext, session); - - IVMRootLayoutNode launchNode = new StandardLaunchRootLayoutNode(this, launch); - // Container node to contain all processes and threads - IVMLayoutNode containerNode = new ContainerLayoutNode(this, getSession()); - IVMLayoutNode processesNode = new StandardProcessLayoutNode(this); - launchNode.setChildNodes(new IVMLayoutNode[] { containerNode, processesNode}); - - IVMLayoutNode threadsNode = new ThreadLayoutNode(this, getSession()); - containerNode.setChildNodes(new IVMLayoutNode[] { threadsNode }); - - IVMLayoutNode stackFramesNode = new StackFramesLayoutNode(this, getSession()); - threadsNode.setChildNodes(new IVMLayoutNode[] { stackFramesNode }); - - setRootLayoutNode(launchNode); - - DebugPlugin.getDefault().addDebugEventListener(this); - DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); - } - - - public void handleDebugEvents(final DebugEvent[] events) { - if (isDisposed()) return; - - // We're in session's executor thread. Re-dispach to VM Adapter - // executor thread and then call root layout node. - try { - getExecutor().execute(new Runnable() { - public void run() { - if (isDisposed()) return; - - for (final DebugEvent event : events) { - IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); - if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { - rootLayoutNode.createDelta( - event, - new DataRequestMonitor<IModelDelta>(getExecutor(), null) { - @Override - public void handleCompleted() { - if (getStatus().isOK()) { - getModelProxy().fireModelChangedNonDispatch(getData()); - } - } - @Override - public String toString() { - return "Result of a delta for debug event: '" + event.toString() + - "' in VMP: '" + LaunchVMProvider.this + "'" + - "\n" + getData(); - } - }); - } - } - }}); - } - catch (RejectedExecutionException e) { - // Ignore. This exception could be thrown if the provider is being - // shut down. - } - } - - @Override - public void dispose() { - DebugPlugin.getDefault().removeDebugEventListener(this); - DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this); - super.dispose(); - } - - public void launchesAdded(ILaunch[] launches) { - handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.ADDED)); - } - - public void launchesRemoved(ILaunch[] launches) { - handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.REMOVED)); - } - - public void launchesChanged(ILaunch[] launches) { - handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.CHANGED)); - } - - public void launchesTerminated(ILaunch[] launches) { - handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.TERMINATED)); - } - - private void handleLaunchesEvent(final LaunchesEvent event) { - if (isDisposed()) return; - - // We're in session's executor thread. Re-dispach to VM Adapter - // executor thread and then call root layout node. - try { - getExecutor().execute(new Runnable() { - public void run() { - if (isDisposed()) return; - - IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); - if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { - rootLayoutNode.createDelta( - event, - new DataRequestMonitor<IModelDelta>(getExecutor(), null) { - @Override - public void handleCompleted() { - if (getStatus().isOK()) { - getModelProxy().fireModelChangedNonDispatch(getData()); - } - } - @Override - public String toString() { - return "Result of a delta for launch event: '" + event.toString() + - "' in VMP: '" + LaunchVMProvider.this + "'" + - "\n" + getData(); - } - }); - } - }}); - } - catch (RejectedExecutionException e) { - // Ignore. This exception could be thrown if the provider is being - // shut down. - } - } -} diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/ThreadLayoutNode.java b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/ThreadLayoutNode.java deleted file mode 100644 index 43d6e788e..000000000 --- a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/ThreadLayoutNode.java +++ /dev/null @@ -1,201 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - * Ericsson - Modified for multi threaded functionality - *******************************************************************************/ -package org.eclipse.tm.internal.tcf.dsf.ui; - -import java.util.List; -import java.util.Map; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.debug.service.INativeProcesses; -import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.service.INativeProcesses.IThreadDMData; -import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl.IStartedDMEvent; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; -import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; -import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; -import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; -import org.eclipse.debug.ui.DebugUITools; -import org.eclipse.debug.ui.IDebugUIConstants; -import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFExecutionDMC; - - -@SuppressWarnings("restriction") -public class ThreadLayoutNode extends AbstractDMVMLayoutNode { - - public ThreadLayoutNode(AbstractVMProvider provider, DsfSession session) { - super(provider, session, IRunControl.IExecutionDMContext.class); - } - - @Override - protected void updateElementsInSessionThread(final IChildrenUpdate update) { - if (!checkService(IRunControl.class, null, update)) return; - final IContainerDMContext contDmc = findDmcInPath(update.getElementPath(), IContainerDMContext.class); - - if (contDmc == null) { - handleFailedUpdate(update); - return; - } - - getServicesTracker().getService(IRunControl.class).getExecutionContexts(contDmc, - new DataRequestMonitor<IExecutionDMContext[]>(getSession().getExecutor(), null){ - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - handleFailedUpdate(update); - return; - } - fillUpdateWithVMCs(update, getData()); - update.done(); - } - }); - } - - @Override - protected void updateLabelInSessionThread(ILabelUpdate[] updates) { - for (final ILabelUpdate update : updates) { - if (!checkService(IRunControl.class, null, update)) continue; - if (!checkService(INativeProcesses.class, null, update)) continue; - - final IExecutionDMContext dmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class); - - INativeProcesses processes = getServicesTracker().getService(INativeProcesses.class); - - String imageKey = null; - if (getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) { - imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED; - } - else { - imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING; - } - update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); - - // Find the Reason for the State - final StringBuilder reason = new StringBuilder(); - getServicesTracker().getService(IRunControl.class).getExecutionData(dmc, - new DataRequestMonitor<IExecutionDMData>(getSession().getExecutor(), null) { - @Override - public void handleCompleted(){ - if (!getStatus().isOK()) { - update.done(); - return; - } - if(getData().getStateChangeReason() != null){ - reason.append(": " + getData().getStateChangeReason() ); //$NON-NLS-1$ - } - } - }); - - getServicesTracker().getService(INativeProcesses.class).getThreadData( - processes.getThreadForDebugContext(dmc), - new DataRequestMonitor<IThreadDMData>(getSession().getExecutor(), null) { - @Override - public void handleCompleted() { - if (!getStatus().isOK()) { - update.done(); - return; - } - final StringBuilder builder = new StringBuilder("Thread["); //$NON-NLS-1$ - builder.append(((TCFDSFExecutionDMC)dmc).getTcfContextId()); - builder.append("] "); //$NON-NLS-1$ - builder.append(getData().getId()); - builder.append(getData().getName()); - if(getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) - builder.append(" (Suspended"); //$NON-NLS-1$ - else - builder.append(" (Running"); //$NON-NLS-1$ - // Reason will be null before ContainerSuspendEvent is fired - if(reason.length() > 0 ) - builder.append(reason); - builder.append(")"); //$NON-NLS-1$ - update.setLabel(builder.toString(), 0); - update.done(); - } - }); - } - } - - @Override - protected int getNodeDeltaFlagsForDMEvent(IDMEvent<?> e) { - if (e instanceof IRunControl.IContainerResumedDMEvent || - e instanceof IRunControl.IContainerSuspendedDMEvent || - e instanceof IStartedDMEvent || - e instanceof IExitedDMEvent) { - return IModelDelta.CONTENT; - } - if (e instanceof IRunControl.IResumedDMEvent || - e instanceof IRunControl.ISuspendedDMEvent) { - return IModelDelta.STATE; - } - return IModelDelta.NO_CHANGE; - } - - @Override - protected void buildDeltaForDMEvent(final IDMEvent<?> e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { - if (e instanceof IRunControl.IContainerResumedDMEvent || e instanceof IRunControl.IContainerSuspendedDMEvent) { - // Since IContainerDMContext sub-classes IExecutionDMContext, container - // events require special processing: - // Retrieve all the thread elements and mark their state as changed. - // Then pass these elements to the child layout nodes for processing - final Map<IVMLayoutNode,Integer> childNodeDeltas = getChildNodesWithDeltaFlags(e); - if (childNodeDeltas.size() == 0) { - // There are no child nodes with deltas, just return to parent. - requestMonitor.done(); - return; - } - - // Calculate the index of this node by retrieving all the - // elements and then finding the DMC that the event is for. - updateElements(new ElementsUpdate( - new DataRequestMonitor<List<Object>>(getExecutor(), null) { - @Override - protected void handleCompleted() { - if (isDisposed()) return; - - // Check for an empty list of elements. If it's empty then we - // don't have to call the children nodes, so return here. - // No need to propagate error, there's no means or need to display it. - if (!getStatus().isOK() || getData().isEmpty()) { - requestMonitor.done(); - return; - } - - for (int i = 0; i < getData().size(); i++) { - IVMContext vmc = (IVMContext)getData().get(i); - VMDelta delta = parentDelta.addNode(vmc, nodeOffset + i, IModelDelta.STATE); - callChildNodesToBuildDelta(childNodeDeltas, delta, e, requestMonitor); - if (vmc.equals(getData().get(i))) break; - } - } - }, - parentDelta)); - return; - } - else if (e instanceof IRunControl.IResumedDMEvent || e instanceof IRunControl.ISuspendedDMEvent) { - parentDelta.addNode(new DMVMContext(e.getDMContext()), IModelDelta.STATE); - super.buildDeltaForDMEvent(e, parentDelta, nodeOffset, requestMonitor); - } - else { - super.buildDeltaForDMEvent(e, parentDelta, nodeOffset, requestMonitor); - } - } -} diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/actions/TcfTerminateCommand.java b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/actions/TcfTerminateCommand.java new file mode 100644 index 000000000..331352409 --- /dev/null +++ b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/actions/TcfTerminateCommand.java @@ -0,0 +1,27 @@ +package org.eclipse.tm.internal.tcf.dsf.ui.actions; + +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.debug.core.commands.IDebugCommandRequest; +import org.eclipse.debug.core.commands.IEnabledStateRequest; +import org.eclipse.debug.core.commands.ITerminateHandler; + +public class TcfTerminateCommand implements ITerminateHandler { + + public TcfTerminateCommand(DsfSession session) { + + } + + public void dispose() { + + } + + public void canExecute(IEnabledStateRequest request) { + // TODO Auto-generated method stub + + } + + public boolean execute(IDebugCommandRequest request) { + // TODO Auto-generated method stub + return false; + } +} diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/LaunchDialogTabGroup.java b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/launch/LaunchDialogTabGroup.java index eb47de6b9..aad3b3e63 100644 --- a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/LaunchDialogTabGroup.java +++ b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/launch/LaunchDialogTabGroup.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.tm.internal.tcf.dsf.ui; +package org.eclipse.tm.internal.tcf.dsf.ui.launch; import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; import org.eclipse.debug.ui.CommonTab; diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/viewmodel/ExecutableContextLayoutNode.java b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/viewmodel/ExecutableContextLayoutNode.java new file mode 100644 index 000000000..acae2eca1 --- /dev/null +++ b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/viewmodel/ExecutableContextLayoutNode.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2006 Ericsson and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + * Wind River Systems - reused for TCF connection type + *******************************************************************************/ + +package org.eclipse.tm.internal.tcf.dsf.ui.viewmodel; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.DsfRunnable; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IStartedDMEvent; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFExecutionDMC; +import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFRunControl; +import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFRunControlState; +import org.eclipse.tm.tcf.util.TCFDataCache; + + +@SuppressWarnings("restriction") +public class ExecutableContextLayoutNode extends AbstractDMVMNode implements IElementLabelProvider { + + public ExecutableContextLayoutNode(AbstractDMVMProvider provider, DsfSession session) { + super(provider, session, IRunControl.IExecutionDMContext.class); + } + + private void doneViewerUpdate(final IViewerUpdate req) { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + req.done(); + } + }); + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(IRunControl.class, null, update)) return; + + final TCFDSFExecutionDMC dmc = findDmcInPath(update.getViewerInput(), + update.getElementPath(), TCFDSFExecutionDMC.class); + + getServicesTracker().getService(TCFDSFRunControl.class).getAllContexts(dmc, + new DataRequestMonitor<IExecutionDMContext[]>(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + } + else { + fillUpdateWithVMCs(update, getData()); + doneViewerUpdate(update); + } + } + } + ); + } + + public void update(final ILabelUpdate[] updates) { + try { + getSession().getExecutor().execute(new DsfRunnable() { + public void run() { + updateLabelInSessionThread(updates); + } + }); + } + catch (RejectedExecutionException e) { + for (ILabelUpdate update : updates) { + handleFailedUpdate(update); + } + } + } + + private void updateLabelInSessionThread(final ILabelUpdate[] updates) { + TCFDataCache<?> pending = null; + for (final ILabelUpdate update : updates) { + if (!checkService(TCFDSFRunControl.class, null, update)) continue; + TCFDSFExecutionDMC dmc = (TCFDSFExecutionDMC)findDmcInPath(update.getViewerInput(), + update.getElementPath(), IContainerDMContext.class); + if (!dmc.run_control_context_cache.validate()) pending = dmc.run_control_context_cache; + else if (!dmc.run_control_state_cache.validate()) pending = dmc.run_control_state_cache; + } + if (pending != null) { + pending.wait(new Runnable() { + public void run() { + updateLabelInSessionThread(updates); + } + }); + return; + } + + for (final ILabelUpdate update : updates) { + if (!checkService(TCFDSFRunControl.class, null, update)) continue; + TCFDSFExecutionDMC dmc = (TCFDSFExecutionDMC)findDmcInPath(update.getViewerInput(), + update.getElementPath(), IContainerDMContext.class); + + org.eclipse.tm.tcf.services.IRunControl.RunControlContext rc = dmc.run_control_context_cache.getData(); + String image = null; + if (rc == null) { + image = IDebugUIConstants.IMG_ACT_DEBUG; + } + else if (!rc.hasState()) { + image = IDebugUIConstants.IMG_OBJS_DEBUG_TARGET; + } + else { + TCFDSFRunControlState state = dmc.run_control_state_cache.getData(); + if (state != null && state.is_suspended) { + image = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED; + } + else { + image = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING; + } + } + update.setImageDescriptor(DebugUITools.getImageDescriptor(image), 0); + + update.setLabel(dmc.getTcfContextId(), 0); + doneViewerUpdate(update); + } + } + + public int getDeltaFlags(Object e) { + if (e instanceof IStartedDMEvent || e instanceof IExitedDMEvent) { + return IModelDelta.CONTENT; + } + if (e instanceof IRunControl.IResumedDMEvent || e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.STATE; + } + return IModelDelta.NO_CHANGE; + } + + public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor requestMonitor) { + if (e instanceof IRunControl.IResumedDMEvent || e instanceof IRunControl.ISuspendedDMEvent) { + parentDelta.addNode(new DMVMContext(((IDMEvent<?>)e).getDMContext()), IModelDelta.STATE); + } + else if (e instanceof IStartedDMEvent || e instanceof IExitedDMEvent) { + parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT); + //parentDelta.addNode(createVMContext(((IDMEvent<?>)e).getDMContext()), IModelDelta.CONTENT); + } + requestMonitor.done(); + } +} diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/viewmodel/LaunchVMProvider.java b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/viewmodel/LaunchVMProvider.java new file mode 100644 index 000000000..477e3376a --- /dev/null +++ b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/viewmodel/LaunchVMProvider.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tm.internal.tcf.dsf.ui.viewmodel; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.LaunchRootVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.StackFramesVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.LaunchRootVMNode.LaunchesEvent; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchesListener2; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + + +@SuppressWarnings("restriction") +public class LaunchVMProvider extends AbstractDMVMProvider +implements IDebugEventSetListener, ILaunchesListener2 { + + @ThreadSafe + public LaunchVMProvider(AbstractVMAdapter adapter, + IPresentationContext presentationContext, + DsfSession session, ILaunch launch) { + super(adapter, presentationContext, session); + + IRootVMNode launch_node = new LaunchRootVMNode(this); + setRootNode(launch_node); + + IVMNode threads_node = new ExecutableContextLayoutNode(this, getSession()); + addChildNodes(launch_node, new IVMNode[] { threads_node }); + + IVMNode stack_frames_node = new StackFramesVMNode(this, getSession()); + addChildNodes(threads_node, new IVMNode[] { threads_node, stack_frames_node }); + + DebugPlugin.getDefault().addDebugEventListener(this); + DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); + } + + + public void handleDebugEvents(final DebugEvent[] events) { + if (isDisposed()) return; + + // We're in session's executor thread. Re-dispatch to VM Adapter + // executor thread and then call root layout node. + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + + for (final DebugEvent event : events) { + handleEvent(event); + } + } + }); + } + catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } + } + + @Override + public void dispose() { + DebugPlugin.getDefault().removeDebugEventListener(this); + DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this); + super.dispose(); + } + + public void launchesAdded(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.ADDED)); + } + + public void launchesRemoved(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.REMOVED)); + } + + public void launchesChanged(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.CHANGED)); + } + + public void launchesTerminated(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.TERMINATED)); + } + + private void handleLaunchesEvent(final LaunchesEvent event) { + if (isDisposed()) return; + + // We're in session's executor thread. Re-dispach to VM Adapter + // executor thread and then call root layout node. + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + + IRootVMNode rootLayoutNode = getRootVMNode(); + if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { + handleEvent(event); + } + }}); + } + catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } + } +} diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/viewmodel/RegisterVMProvider.java b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/viewmodel/RegisterVMProvider.java new file mode 100644 index 000000000..8822dc419 --- /dev/null +++ b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/viewmodel/RegisterVMProvider.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tm.internal.tcf.dsf.ui.viewmodel; + +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.numberformat.FormattedValuePreferenceStore; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterBitFieldVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterColumnPresentation; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterGroupVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterVMNode; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.SyncRegisterDataAccess; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.BreakpointHitUpdatePolicy; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IRootVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.RootDMVMNode; +import org.eclipse.dd.dsf.ui.viewmodel.update.AutomaticUpdatePolicy; +import org.eclipse.dd.dsf.ui.viewmodel.update.IVMUpdatePolicy; +import org.eclipse.dd.dsf.ui.viewmodel.update.ManualUpdatePolicy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; + +/** + * Provides the VIEW MODEL for the DEBUG MODEL REGISTER view. + */ +@SuppressWarnings("restriction") +public class RegisterVMProvider extends AbstractDMVMProvider implements IPropertyChangeListener { + + /* + * Current default for register formatting. + */ + public RegisterVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) { + super(adapter, context, session); + + context.addPropertyChangeListener(this); + + /* + * Create the register data access routines. + */ + SyncRegisterDataAccess regAccess = new SyncRegisterDataAccess(session) ; + + /* + * Create the top level node to deal with the root selection. + */ + IRootVMNode rootNode = new RootDMVMNode(this); + + IVMNode registerGroupNode = new RegisterGroupVMNode(this, getSession(), regAccess); + IVMNode registerNode = new RegisterVMNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), regAccess); + IVMNode bitFieldNode = new RegisterBitFieldVMNode(FormattedValuePreferenceStore.getDefault(), this, getSession(), regAccess); + + /* + * Create the Group nodes next. They represent the first level shown in the view. + */ + + addChildNodes(rootNode, new IVMNode[] { registerGroupNode, registerNode }); + + /* + * Create the next level which is the registers themselves. + */ + addChildNodes(registerGroupNode, new IVMNode[] { registerNode, bitFieldNode }); + + /* + * Create the next level which is the bitfield level. + */ + addChildNodes(registerNode, new IVMNode[] { bitFieldNode }); + + /* + * Now set this schema set as the layout set. + */ + setRootNode(rootNode); + } + + @Override + protected IVMUpdatePolicy[] createUpdateModes() { + return new IVMUpdatePolicy[] { new AutomaticUpdatePolicy(), new ManualUpdatePolicy(), new BreakpointHitUpdatePolicy() }; + } + + @Override + public void dispose() { + getPresentationContext().removePropertyChangeListener(this); + super.dispose(); + } + + @Override + public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { + return new RegisterColumnPresentation(); + } + + @Override + public String getColumnPresentationId(IPresentationContext context, Object element) { + return RegisterColumnPresentation.ID; + } + + public void propertyChange(PropertyChangeEvent event) { + handleEvent(event); + } +} diff --git a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/ViewModelAdapter.java b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/viewmodel/ViewModelAdapter.java index 3ee862998..051e4abfa 100644 --- a/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/ViewModelAdapter.java +++ b/plugins/org.eclipse.tm.tcf.dsf.ui/src/org/eclipse/tm/internal/tcf/dsf/ui/viewmodel/ViewModelAdapter.java @@ -8,15 +8,15 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.tm.internal.tcf.dsf.ui; +package org.eclipse.tm.internal.tcf.dsf.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.register.RegisterVMProvider; -import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMProvider; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionVMProvider; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules.ModulesVMProvider; +import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.VariableVMProvider; import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMAdapter; -import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter; import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; import org.eclipse.debug.ui.IDebugUIConstants; @@ -42,7 +42,7 @@ public class ViewModelAdapter extends AbstractDMVMAdapter { } @Override - protected AbstractDMVMProvider createViewModelProvider(IPresentationContext context) { + protected IVMProvider createViewModelProvider(IPresentationContext context) { if (IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) { return new LaunchVMProvider(this, context, getSession(), launch); } @@ -55,6 +55,9 @@ public class ViewModelAdapter extends AbstractDMVMAdapter { if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { return new ExpressionVMProvider(this, context, getSession()); } + if (IDebugUIConstants.ID_MODULE_VIEW.equals(context.getId()) ) { + return new ModulesVMProvider(this, context, getSession()); + } return null; } } diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunch.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunch.java index b48b21853..641faed20 100644 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunch.java +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunch.java @@ -38,12 +38,11 @@ public class TCFDSFLaunch extends TCFLaunch { if (channel != null) { RequestMonitor monitor = new RequestMonitor(executor, null) { @Override - protected void handleOK() { + protected void handleSuccess() { done.run(); } }; - TCFDSFLaunchSequence seq = new TCFDSFLaunchSequence(session, TCFDSFLaunch.this, monitor); - executor.execute(seq); + executor.execute(new TCFDSFLaunchSequence(session, TCFDSFLaunch.this, monitor)); } else { done.run(); @@ -52,6 +51,17 @@ public class TCFDSFLaunch extends TCFLaunch { }); } + @Override + protected void runShutdownSequence(final Runnable done) { + RequestMonitor monitor = new RequestMonitor(executor, null) { + @Override + protected void handleSuccess() { + TCFDSFLaunch.super.runShutdownSequence(done); + } + }; + executor.execute(new TCFDSFShutdownSequence(session, TCFDSFLaunch.this, monitor)); + } + public DsfExecutor getDsfExecutor() { return executor; } diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunchSequence.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunchSequence.java index b9c996085..6c04def94 100644 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunchSequence.java +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFLaunchSequence.java @@ -12,14 +12,13 @@ package org.eclipse.tm.internal.tcf.dsf.launch; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.debug.service.StepQueueManager; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFBreakpoints; import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFMemory; -import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFNativeProcesses; import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFRegisters; import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFRunControl; import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFStack; -import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFStepQueueManager; import org.eclipse.tm.tcf.protocol.IChannel; @@ -34,19 +33,13 @@ class TCFDSFLaunchSequence extends Sequence { new Step() { @Override public void execute(RequestMonitor monitor) { - new TCFDSFNativeProcesses(session, channel, monitor); + new TCFDSFRunControl(launch.getLaunchConfiguration(), session, channel, monitor); } }, new Step() { @Override public void execute(RequestMonitor monitor) { - new TCFDSFRunControl(session, channel, monitor); - } - }, - new Step() { - @Override - public void execute(RequestMonitor monitor) { - new TCFDSFStepQueueManager(session).initialize(monitor); + new StepQueueManager(session).initialize(monitor); } }, new Step() { diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFShutdownSequence.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFShutdownSequence.java new file mode 100644 index 000000000..9478bf0a2 --- /dev/null +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFShutdownSequence.java @@ -0,0 +1,117 @@ +package org.eclipse.tm.internal.tcf.dsf.launch; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.concurrent.Sequence; +import org.eclipse.dd.dsf.debug.service.StepQueueManager; +import org.eclipse.dd.dsf.service.DsfServicesTracker; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.tm.internal.tcf.dsf.Activator; +import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFBreakpoints; +import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFMemory; +import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFRegisters; +import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFRunControl; +import org.eclipse.tm.internal.tcf.dsf.services.TCFDSFStack; + +class TCFDSFShutdownSequence extends Sequence { + + private final String session_id; + private final Step[] steps; + private DsfServicesTracker tracker; + + TCFDSFShutdownSequence(final DsfSession session, final TCFDSFLaunch launch, RequestMonitor monitor) { + super(session.getExecutor(), monitor); + session_id = session.getId(); + steps = new Step[] { + new Step() { + @Override + public void execute(RequestMonitor monitor) { + // Initialize services tracker. + tracker = new DsfServicesTracker(Activator.getBundleContext(), session_id); + monitor.done(); + } + + @Override + public void rollBack(RequestMonitor monitor) { + // In case the shutdown sequence aborts, + // ensure that the tracker is properly disposed. + tracker.dispose(); + tracker = null; + monitor.done(); + } + }, + new Step() { + @Override + public void execute(RequestMonitor monitor) { + shutdownService(TCFDSFBreakpoints.class, monitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor monitor) { + shutdownService(TCFDSFRegisters.class, monitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor monitor) { + shutdownService(TCFDSFMemory.class, monitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor monitor) { + shutdownService(TCFDSFStack.class, monitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor monitor) { + shutdownService(StepQueueManager.class, monitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor monitor) { + shutdownService(TCFDSFRunControl.class, monitor); + } + }, + new Step() { + @Override + public void execute(RequestMonitor monitor) { + tracker.dispose(); + tracker = null; + monitor.done(); + } + } + }; + } + + private void shutdownService(Class<?> clazz, final RequestMonitor requestMonitor) { + IDsfService service = (IDsfService)tracker.getService(clazz); + if (service != null) { + service.shutdown(new RequestMonitor(getExecutor(), requestMonitor) { + @Override + protected void handleCompleted() { + if (!isSuccess()) { + Activator.getDefault().getLog().log(getStatus()); + } + requestMonitor.done(); + } + }); + } + else { + requestMonitor.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, + "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ + requestMonitor.done(); + } + } + + @Override + public Step[] getSteps() { + return steps; + } +} diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/IDataRequest.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/IDataRequest.java deleted file mode 100644 index d064448fe..000000000 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/IDataRequest.java +++ /dev/null @@ -1,17 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems, Inc. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.tm.internal.tcf.dsf.services; - -public interface IDataRequest { - - void cancel(); - void done(); -} diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFAddress.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFAddress.java index ec723ed95..3de969429 100644 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFAddress.java +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFAddress.java @@ -18,6 +18,7 @@ public final class TCFAddress implements IAddress { private final BigInteger addr; + // TODO: TCFAddress should include memory space ID public TCFAddress(Number addr) { if (addr instanceof BigInteger) this.addr = (BigInteger)addr; else this.addr = new BigInteger(addr.toString(), 10); diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFBreakpoints.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFBreakpoints.java index 6b1e00502..0d3c7cd00 100644 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFBreakpoints.java +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFBreakpoints.java @@ -10,12 +10,21 @@ *******************************************************************************/ package org.eclipse.tm.internal.tcf.dsf.services; +import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Hashtable; import java.util.Map; +import java.util.Set; +import org.eclipse.cdt.core.IAddress; import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; @@ -35,11 +44,10 @@ import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch; import org.eclipse.tm.internal.tcf.dsf.Activator; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IToken; +import org.eclipse.tm.tcf.services.IBreakpoints; +import org.eclipse.tm.tcf.util.TCFDataCache; import org.osgi.framework.BundleContext; - -// TODO IBreakpointHitEvent - public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse.dd.dsf.debug.service.IBreakpoints { private class BreakpointDMC extends AbstractDMContext implements IBreakpointDMContext { @@ -47,6 +55,7 @@ public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse final String id; final IBreakpoint bp; final TCFDataCache<Map<String,Object>> status; + final Set<IBreakpointsTargetDMContext> targets; boolean disposed; @@ -61,28 +70,18 @@ public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse assert command == null; assert !disposed; if (tcf_bpt_service == null) { - data = null; - valid = true; + reset(null); return true; } command = tcf_bpt_service.getStatus(id, new org.eclipse.tm.tcf.services.IBreakpoints.DoneGetStatus() { public void doneGetStatus(IToken token, Exception err, Map<String,Object> status) { - if (command != token) return; - command = null; - if (err != null) { - data = null; - error = err; - } - else { - data = status; - } - valid = true; - validate(); + set(token, err, status); } }); return false; } }; + targets = new HashSet<IBreakpointsTargetDMContext>(); } @Override @@ -98,80 +97,173 @@ public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse void dispose() { assert !disposed; cache.remove(id); + for (IBreakpointsTargetDMContext t : targets.toArray( + new IBreakpointsTargetDMContext[targets.size()])) onRemoved(t); + assert targets.isEmpty(); disposed = true; } + + void onAdded(final IBreakpointsTargetDMContext t) { + targets.add(t); + IBreakpointsAddedEvent e = new IBreakpointsAddedEvent() { + public IBreakpointsTargetDMContext getDMContext() { + return t; + } + public IBreakpointDMContext[] getBreakpoints() { + return new IBreakpointDMContext[]{ BreakpointDMC.this }; + } + }; + getSession().dispatchEvent(e, getProperties()); + } + + void onUpdated(final IBreakpointsTargetDMContext t) { + assert targets.contains(t); + IBreakpointsUpdatedEvent e = new IBreakpointsUpdatedEvent() { + public IBreakpointsTargetDMContext getDMContext() { + return t; + } + public IBreakpointDMContext[] getBreakpoints() { + return new IBreakpointDMContext[]{ BreakpointDMC.this }; + } + }; + getSession().dispatchEvent(e, getProperties()); + } + + void onRemoved(final IBreakpointsTargetDMContext t) { + targets.remove(t); + IBreakpointsRemovedEvent e = new IBreakpointsRemovedEvent() { + public IBreakpointsTargetDMContext getDMContext() { + return t; + } + public IBreakpointDMContext[] getBreakpoints() { + return new IBreakpointDMContext[]{ BreakpointDMC.this }; + } + }; + getSession().dispatchEvent(e, getProperties()); + } } private class BreakpointData implements IBreakpointDMData { final IBreakpoint bp; - final BreakpointStatus status; + final Map<String,Object> attrs; + final Map<String,Object> status; + final String file; - BreakpointData(IBreakpoint bp, BreakpointStatus status) { + @SuppressWarnings("unchecked") + BreakpointData(IBreakpoint bp, Map<String,Object> status) throws CoreException, IOException { this.bp = bp; this.status = status; + attrs = bp.getMarker().getAttributes(); + IResource resource = bp.getMarker().getResource(); + if (resource == ResourcesPlugin.getWorkspace().getRoot()) { + file = null; + } + else { + IPath p = resource.getRawLocation(); + if (p == null) file = null; + else file = p.toFile().getCanonicalPath(); + } } public IBreakpoint getPlatformBreakpoint() { return bp; } - public BreakpointStatus getStatus() { + public Map<String,Object> getStatus() { return status; } + + @SuppressWarnings("unchecked") + public IAddress[] getAddresses() { + if (status == null) return null; + Map<String,Collection<Number>> arr = (Map<String,Collection<Number>>)status.get(IBreakpoints.STATUS_PLANTED); + if (arr == null) return null; + int cnt = 0; + for (Collection<Number> c : arr.values()) cnt += c.size(); + IAddress[] res = new IAddress[cnt]; + int pos = 0; + for (Collection<Number> c : arr.values()) { + for (Number addr : c) res[pos++] = new TCFAddress(addr); + } + return res; + } + + public String getBreakpointType() { + // TODO Auto-generated method stub + return null; + } + + public String getCondition() { + return (String)attrs.get(ITCFConstants.ID_TCF_DEBUG_MODEL + '.' + IBreakpoints.PROP_CONDITION); + } + + public String getExpression() { + // TODO Auto-generated method stub + return null; + } + + public String getFileName() { + return file; + } + + public String getFunctionName() { + // TODO Auto-generated method stub + return null; + } + + public int getIgnoreCount() { + Integer count = (Integer)attrs.get(ITCFConstants.ID_TCF_DEBUG_MODEL + '.' + IBreakpoints.PROP_SKIP_COUNT); + if (count != null) return count.intValue(); + return 0; + } + + public int getLineNumber() { + Integer line = (Integer)attrs.get(IMarker.LINE_NUMBER); + if (line != null) return line.intValue(); + return 0; + } + + public boolean isEnabled() { + Boolean enabled = (Boolean)attrs.get(IBreakpoint.ENABLED); + return enabled != null && enabled.booleanValue() && bp_manager.isEnabled(); + } } private final ITCFBreakpointListener bp_listener = new ITCFBreakpointListener() { + @SuppressWarnings("unchecked") public void breakpointStatusChanged(String id) { final BreakpointDMC dmc = cache.get(id); if (dmc != null) { - Map<String, Object> map = launch.getBreakpointsStatus().getStatus(dmc.id); + TCFDSFRunControl rc = getServicesTracker().getService(TCFDSFRunControl.class); + Map<String,Object> map = launch.getBreakpointsStatus().getStatus(dmc.id); dmc.status.reset(map); - IBreakpointDMEvent e = null; - if (map == null) { - e = new IBreakpointUninstalledDMEvent() { - public IBreakpointDMContext getDMContext() { - return dmc; - } - }; - } - else if (map.get(org.eclipse.tm.tcf.services.IBreakpoints.STATUS_ERROR) != null) { - e = new IBreakpointInstallFailedDMEvent() { - public IBreakpointDMContext getDMContext() { - return dmc; - } - }; - } - else if (map.get(org.eclipse.tm.tcf.services.IBreakpoints.STATUS_PLANTED) != null) { - e = new IBreakpointInstalledDMEvent() { - public IBreakpointDMContext getDMContext() { - return dmc; - } - }; + Set<IBreakpointsTargetDMContext> add_targets = new HashSet<IBreakpointsTargetDMContext>(); + Set<IBreakpointsTargetDMContext> rem_targets = new HashSet<IBreakpointsTargetDMContext>(); + if (map != null) { + Map<String,Collection<Number>> arr = (Map<String,Collection<Number>>)map.get(IBreakpoints.STATUS_PLANTED); + if (arr != null) { + for (String ctx_id : arr.keySet()) add_targets.add(rc.getContext(ctx_id)); + } } - else { - e = new IBreakpointUninstalledDMEvent() { - public IBreakpointDMContext getDMContext() { - return dmc; - } - }; + for (IBreakpointsTargetDMContext t : dmc.targets) { + if (add_targets.contains(t)) { + dmc.onUpdated(t); + add_targets.remove(t); + } + else { + rem_targets.add(t); + } } - getSession().dispatchEvent(e, getProperties()); + for (IBreakpointsTargetDMContext t : rem_targets) dmc.onRemoved(t); + for (IBreakpointsTargetDMContext t : add_targets) dmc.onAdded(t); } } public void breakpointRemoved(String id) { final BreakpointDMC dmc = cache.get(id); - if (dmc != null) { - dmc.dispose(); - IBreakpointDMEvent e = new IBreakpointUninstalledDMEvent() { - public IBreakpointDMContext getDMContext() { - return dmc; - } - }; - getSession().dispatchEvent(e, getProperties()); - } + if (dmc != null) dmc.dispose(); } }; @@ -179,6 +271,7 @@ public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse private final IChannel channel; private final org.eclipse.tm.tcf.services.IBreakpoints tcf_bpt_service; private final Map<String,BreakpointDMC> cache = new HashMap<String,BreakpointDMC>(); + private final IBreakpointManager bp_manager = DebugPlugin.getDefault().getBreakpointManager(); public TCFDSFBreakpoints(DsfSession session, TCFLaunch launch, final RequestMonitor monitor) { super(session); @@ -188,7 +281,7 @@ public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse tcf_bpt_service = channel.getRemoteService(org.eclipse.tm.tcf.services.IBreakpoints.class); initialize(new RequestMonitor(getExecutor(), monitor) { @Override - protected void handleOK() { + protected void handleSuccess() { String[] class_names = { org.eclipse.dd.dsf.debug.service.IBreakpoints.class.getName(), TCFDSFBreakpoints.class.getName() @@ -210,8 +303,7 @@ public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse return Activator.getBundleContext(); } - public void getAllBreakpoints(IDMContext ctx, DataRequestMonitor<IBreakpointDMContext[]> rm) { - IBreakpointManager bp_manager = DebugPlugin.getDefault().getBreakpointManager(); + public void getBreakpoints(IBreakpointsTargetDMContext ctx, DataRequestMonitor<IBreakpointDMContext[]> rm) { TCFBreakpointsModel m = TCFBreakpointsModel.getBreakpointsModel(); IBreakpoint[] arr = bp_manager.getBreakpoints(ITCFConstants.ID_TCF_DEBUG_MODEL); ArrayList<IBreakpointDMContext> l = new ArrayList<IBreakpointDMContext>(); @@ -233,36 +325,13 @@ public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse rm.done(); } - public void getBreakpoints(IDMContext dmc, IBreakpoint bp, DataRequestMonitor<IBreakpointDMContext[]> rm) { - TCFBreakpointsModel m = TCFBreakpointsModel.getBreakpointsModel(); - ArrayList<IBreakpointDMContext> l = new ArrayList<IBreakpointDMContext>(); - if (m.isSupported(channel, bp)) { - IMarker marker = bp.getMarker(); - String id = marker.getAttribute(ITCFConstants.ID_TCF_DEBUG_MODEL + - '.' + org.eclipse.tm.tcf.services.IBreakpoints.PROP_ID, (String)null); - if (id != null) { - BreakpointDMC c = cache.get(id); - if (c == null) c = new BreakpointDMC(this, id, bp); - l.add(c); - } - } - rm.setData(l.toArray(new IBreakpointDMContext[l.size()])); - rm.done(); - } - - public void getBreakpointData(final IDMContext dmc, final DataRequestMonitor<IBreakpointDMData> rm) { + public void getBreakpointDMData(final IBreakpointDMContext dmc, final DataRequestMonitor<IBreakpointDMData> rm) { if (dmc instanceof BreakpointDMC) { BreakpointDMC bp = (BreakpointDMC)dmc; if (!bp.status.validate()) { - bp.status.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { - getBreakpointData(dmc, rm); + bp.status.wait(new Runnable() { + public void run() { + getBreakpointDMData(dmc, rm); } }); return; @@ -273,17 +342,14 @@ public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse rm.done(); return; } - Map<String,Object> map = bp.status.getData(); - BreakpointStatus status = BreakpointStatus.FILTERED_OUT; - if (map != null) { - if (map.get(org.eclipse.tm.tcf.services.IBreakpoints.STATUS_ERROR) != null) { - status = BreakpointStatus.FAILED_TO_INSTALL; - } - else if (map.get(org.eclipse.tm.tcf.services.IBreakpoints.STATUS_PLANTED) != null) { - status = BreakpointStatus.INSTALLED; - } + try { + rm.setData(new BreakpointData(bp.bp, bp.status.getData())); + } + catch (Exception x) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Data error", x)); //$NON-NLS-1$ + } - rm.setData(new BreakpointData(bp.bp, status)); } else { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, @@ -295,7 +361,7 @@ public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse @SuppressWarnings("unchecked") public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) { if (dmc instanceof BreakpointDMC) { - getBreakpointData((BreakpointDMC)dmc, (DataRequestMonitor<IBreakpointDMData>)rm); + getBreakpointDMData((BreakpointDMC)dmc, (DataRequestMonitor<IBreakpointDMData>)rm); } else { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, @@ -303,4 +369,28 @@ public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse rm.done(); } } + + public void insertBreakpoint(IBreakpointsTargetDMContext context, Map<String,Object> attributes, + DataRequestMonitor<IBreakpointDMContext> rm) { + // Clients are not allowed to call this method. + // Use IBreakpointManager instead. + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Not allowed", new Error())); //$NON-NLS-1$ + rm.done(); + } + + public void removeBreakpoint(IBreakpointDMContext dmc, RequestMonitor rm) { + // Clients are not allowed to call this method. + // Use IBreakpointManager instead. + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Not allowed", new Error())); //$NON-NLS-1$ + rm.done(); + } + + public void updateBreakpoint(IBreakpointDMContext dmc, Map<String,Object> delta, RequestMonitor rm) { + // Clients are not allowed to call this method. + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Not allowed", new Error())); //$NON-NLS-1$ + rm.done(); + } } diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java index 6246cd99d..067a5253f 100644 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java @@ -10,25 +10,131 @@ *******************************************************************************/ package org.eclipse.tm.internal.tcf.dsf.services; +import java.util.HashMap; +import java.util.Map; + import org.eclipse.dd.dsf.datamodel.AbstractDMContext; import org.eclipse.dd.dsf.datamodel.IDMContext; +import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.tm.tcf.protocol.IChannel; +import org.eclipse.tm.tcf.protocol.IToken; +import org.eclipse.tm.tcf.services.IMemory; +import org.eclipse.tm.tcf.services.IRunControl; +import org.eclipse.tm.tcf.services.IRunControl.RunControlContext; +import org.eclipse.tm.tcf.util.TCFDataCache; -public abstract class TCFDSFExecutionDMC extends AbstractDMContext implements IExecutionDMContext, IContainerDMContext { +public abstract class TCFDSFExecutionDMC extends AbstractDMContext + implements IExecutionDMContext, IContainerDMContext, IMemoryDMContext, IBreakpointsTargetDMContext { - interface DataCache { - } + public final TCFDataCache<IMemory.MemoryContext> memory_context_cache; + public final TCFDataCache<RunControlContext> run_control_context_cache; + public final TCFDataCache<Map<String,TCFDSFExecutionDMC>> run_control_children_cache; + public final TCFDataCache<TCFDSFRunControlState> run_control_state_cache; - DataCache stack_frames_cache; - DataCache memory_cache; - DataCache registers_cache; + TCFDataCache<?> stack_frames_cache; + TCFDataCache<?> registers_cache; - TCFDSFExecutionDMC(IDsfService service, IDMContext[] parents) { + TCFDSFExecutionDMC(IChannel channel, IDsfService service, IDMContext[] parents) { super(service, parents); + final IMemory tcf_mem_service = channel.getRemoteService(IMemory.class); + final IRunControl tcf_run_service = channel.getRemoteService(IRunControl.class); + memory_context_cache = new TCFDataCache<IMemory.MemoryContext>(channel) { + @Override + public boolean startDataRetrieval() { + assert command == null; + String id = getTcfContextId(); + if (id == null || tcf_mem_service == null) { + reset(null); + return true; + } + command = tcf_mem_service.getContext(id, + new org.eclipse.tm.tcf.services.IMemory.DoneGetContext() { + public void doneGetContext(IToken token, Exception err, + org.eclipse.tm.tcf.services.IMemory.MemoryContext ctx) { + set(token, err, ctx); + } + }); + return false; + } + }; + run_control_context_cache = new TCFDataCache<RunControlContext>(channel) { + @Override + public boolean startDataRetrieval() { + assert command == null; + String id = getTcfContextId(); + if (id == null || tcf_run_service == null) { + reset(null); + return true; + } + command = tcf_run_service.getContext(id, new IRunControl.DoneGetContext() { + public void doneGetContext(IToken token, Exception err, IRunControl.RunControlContext ctx) { + set(token, err, ctx); + } + }); + return false; + } + }; + run_control_children_cache = new TCFDataCache<Map<String,TCFDSFExecutionDMC>>(channel) { + @Override + public boolean startDataRetrieval() { + assert command == null; + if (tcf_run_service == null) { + reset(null); + return true; + } + String id = getTcfContextId(); + command = tcf_run_service.getChildren(id, new IRunControl.DoneGetChildren() { + public void doneGetChildren(IToken token, Exception err, String[] contexts) { + if (command != token) return; + HashMap<String,TCFDSFExecutionDMC> data = new HashMap<String,TCFDSFExecutionDMC>(); + if (contexts != null) { + for (int i = 0; i < contexts.length; i++) { + String id = contexts[i]; + TCFDSFExecutionDMC n = addChild(id); + data.put(id, n); + } + } + set(token, err, data); + } + }); + return false; + } + }; + run_control_state_cache = new TCFDataCache<TCFDSFRunControlState>(channel) { + @Override + public boolean startDataRetrieval() { + assert command == null; + assert run_control_context_cache.isValid(); + RunControlContext c = run_control_context_cache.getData(); + if (c == null || !c.hasState()) { + reset(null); + return true; + } + command = c.getState(new IRunControl.DoneGetState() { + public void doneGetState(IToken token, Exception err, boolean suspend, String pc, String reason, Map<String,Object> params) { + if (command != token) return; + TCFDSFRunControlState data = new TCFDSFRunControlState(); + data.is_running = !suspend; + data.is_suspended = suspend; + if (suspend) { + data.suspend_pc = pc; + data.suspend_reason = reason; + data.suspend_params = params; + } + set(token, err, data); + } + }); + return false; + } + }; } + public abstract void dispose(); + /** * Get TCF ID of execution context. * @return TCF ID. @@ -41,22 +147,5 @@ public abstract class TCFDSFExecutionDMC extends AbstractDMContext implements IE */ public abstract boolean isDisposed(); - /** - * Validate execution state data. - * @return true if state is valid, false if data retrieval is started. - */ - public abstract boolean validateState(); - - /** - * Add a listener to be activated when state data retrieval is done. - * @param req - listener object. - */ - public abstract void addStateWaitingRequest(IDataRequest req); - - /** - * Get current program counter. This method must be called only when - * execution state data is valid - when validateState() return true. - * @return current program counter address. - */ - public abstract TCFAddress getPC(); + protected abstract TCFDSFExecutionDMC addChild(String id); } diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java index cf40d6a4b..df3e9b873 100644 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java @@ -17,6 +17,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; @@ -24,47 +25,26 @@ import org.eclipse.debug.core.model.MemoryByte; import org.eclipse.tm.internal.tcf.dsf.Activator; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IToken; +import org.eclipse.tm.tcf.services.IMemory; import org.eclipse.tm.tcf.services.IMemory.MemoryContext; import org.eclipse.tm.tcf.services.IMemory.MemoryError; +import org.eclipse.tm.tcf.util.TCFDataCache; import org.osgi.framework.BundleContext; public class TCFDSFMemory extends AbstractDsfService implements org.eclipse.dd.dsf.debug.service.IMemory { - private class MemoryCache implements TCFDSFExecutionDMC.DataCache { + private static class MemoryChangedEvent extends AbstractDMEvent<IMemoryDMContext> implements IMemoryChangedEvent { + IAddress[] fAddresses; + IDMContext fContext; - final TCFDataCache<org.eclipse.tm.tcf.services.IMemory.MemoryContext> context; - - MemoryCache(final IChannel channel, final TCFDSFExecutionDMC exe) { - context = new TCFDataCache<org.eclipse.tm.tcf.services.IMemory.MemoryContext>(channel) { - @Override - public boolean startDataRetrieval() { - assert command == null; - String id = exe.getTcfContextId(); - if (id == null || tcf_mem_service == null) { - data = null; - valid = true; - return true; - } - command = tcf_mem_service.getContext(id, - new org.eclipse.tm.tcf.services.IMemory.DoneGetContext() { - public void doneGetContext(IToken token, Exception err, - org.eclipse.tm.tcf.services.IMemory.MemoryContext ctx) { - if (command != token) return; - command = null; - if (err != null) { - error = err; - } - else { - data = ctx; - } - valid = true; - validate(); - } - }); - return false; - } - }; + public MemoryChangedEvent(IMemoryDMContext context, IAddress[] addresses) { + super(context); + fAddresses = addresses; + } + + public IAddress[] getAddresses() { + return fAddresses; } } @@ -83,7 +63,7 @@ public class TCFDSFMemory extends AbstractDsfService implements org.eclipse.dd.d public void memoryChanged(String context_id, Number[] addr, long[] size) { TCFDSFRunControl rc = getServicesTracker().getService(TCFDSFRunControl.class); TCFDSFExecutionDMC exe = rc.getContext(context_id); - if (exe == null || exe.memory_cache == null) return; + if (exe == null || exe.memory_context_cache == null) return; for (int n = 0; n < addr.length; n++) { long count = size[n]; // TODO: DSF does not support address ranges @@ -97,17 +77,15 @@ public class TCFDSFMemory extends AbstractDsfService implements org.eclipse.dd.d } }; - private final IChannel channel; private final org.eclipse.tm.tcf.services.IMemory tcf_mem_service; public TCFDSFMemory(DsfSession session, IChannel channel, final RequestMonitor monitor) { super(session); - this.channel = channel; tcf_mem_service = channel.getRemoteService(org.eclipse.tm.tcf.services.IMemory.class); if (tcf_mem_service != null) tcf_mem_service.addListener(mem_listener); initialize(new RequestMonitor(getExecutor(), monitor) { @Override - protected void handleOK() { + protected void handleSuccess() { String[] class_names = { org.eclipse.dd.dsf.debug.service.IMemory.class.getName(), TCFDSFMemory.class.getName() @@ -129,7 +107,7 @@ public class TCFDSFMemory extends AbstractDsfService implements org.eclipse.dd.d return Activator.getBundleContext(); } - public void fillMemory(final IDMContext dmc, final IAddress address, final long offset, + public void fillMemory(final IMemoryDMContext dmc, final IAddress address, final long offset, final int word_size, final int count, final byte[] pattern, final RequestMonitor rm) { if (tcf_mem_service == null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, @@ -138,29 +116,22 @@ public class TCFDSFMemory extends AbstractDsfService implements org.eclipse.dd.d } else if (dmc instanceof TCFDSFExecutionDMC) { final TCFDSFExecutionDMC ctx = (TCFDSFExecutionDMC)dmc; - if (ctx.memory_cache == null) ctx.memory_cache = new MemoryCache(channel, ctx); - MemoryCache cache = (MemoryCache)ctx.memory_cache; - if (!cache.context.validate()) { - cache.context.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { + TCFDataCache<IMemory.MemoryContext> cache = ctx.memory_context_cache; + if (!cache.validate()) { + cache.wait(new Runnable() { + public void run() { fillMemory(dmc, address, offset, word_size, count, pattern, rm); } }); return; } - if (cache.context.getError() != null) { + if (cache.getError() != null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Data error", cache.context.getError())); //$NON-NLS-1$ + REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$ rm.done(); return; } - org.eclipse.tm.tcf.services.IMemory.MemoryContext mem = cache.context.getData(); + org.eclipse.tm.tcf.services.IMemory.MemoryContext mem = cache.getData(); if (mem == null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC", null)); //$NON-NLS-1$ @@ -186,7 +157,7 @@ public class TCFDSFMemory extends AbstractDsfService implements org.eclipse.dd.d } } - public void getMemory(final IDMContext dmc, final IAddress address, final long offset, + public void getMemory(final IMemoryDMContext dmc, final IAddress address, final long offset, final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> rm) { if (tcf_mem_service == null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, @@ -195,29 +166,22 @@ public class TCFDSFMemory extends AbstractDsfService implements org.eclipse.dd.d } else if (dmc instanceof TCFDSFExecutionDMC) { final TCFDSFExecutionDMC ctx = (TCFDSFExecutionDMC)dmc; - if (ctx.memory_cache == null) ctx.memory_cache = new MemoryCache(channel, ctx); - MemoryCache cache = (MemoryCache)ctx.memory_cache; - if (!cache.context.validate()) { - cache.context.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { + TCFDataCache<IMemory.MemoryContext> cache = ctx.memory_context_cache; + if (!cache.validate()) { + cache.wait(new Runnable() { + public void run() { getMemory(dmc, address, offset, word_size, count, rm); } }); return; } - if (cache.context.getError() != null) { + if (cache.getError() != null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Data error", cache.context.getError())); //$NON-NLS-1$ + REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$ rm.done(); return; } - org.eclipse.tm.tcf.services.IMemory.MemoryContext mem = cache.context.getData(); + org.eclipse.tm.tcf.services.IMemory.MemoryContext mem = cache.getData(); if (mem == null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC", null)); //$NON-NLS-1$ @@ -237,6 +201,7 @@ public class TCFDSFMemory extends AbstractDsfService implements org.eclipse.dd.d for (int i = 0; i < buffer.length; i++) { res[i] = new MemoryByte(buffer[i]); } + rm.setData(res); rm.done(); } }); @@ -248,7 +213,7 @@ public class TCFDSFMemory extends AbstractDsfService implements org.eclipse.dd.d } } - public void setMemory(final IDMContext dmc, final IAddress address, final long offset, + public void setMemory(final IMemoryDMContext dmc, final IAddress address, final long offset, final int word_size, final int count, final byte[] buffer, final RequestMonitor rm) { if (tcf_mem_service == null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, @@ -257,29 +222,22 @@ public class TCFDSFMemory extends AbstractDsfService implements org.eclipse.dd.d } else if (dmc instanceof TCFDSFExecutionDMC) { final TCFDSFExecutionDMC ctx = (TCFDSFExecutionDMC)dmc; - if (ctx.memory_cache == null) ctx.memory_cache = new MemoryCache(channel, ctx); - MemoryCache cache = (MemoryCache)ctx.memory_cache; - if (!cache.context.validate()) { - cache.context.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { + TCFDataCache<IMemory.MemoryContext> cache = ctx.memory_context_cache; + if (!cache.validate()) { + cache.wait(new Runnable() { + public void run() { setMemory(dmc, address, offset, word_size, count, buffer, rm); } }); return; } - if (cache.context.getError() != null) { + if (cache.getError() != null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Data error", cache.context.getError())); //$NON-NLS-1$ + REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$ rm.done(); return; } - org.eclipse.tm.tcf.services.IMemory.MemoryContext mem = cache.context.getData(); + org.eclipse.tm.tcf.services.IMemory.MemoryContext mem = cache.getData(); if (mem == null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC", null)); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFNativeProcesses.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFNativeProcesses.java deleted file mode 100644 index b1f66dde4..000000000 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFNativeProcesses.java +++ /dev/null @@ -1,614 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.tm.internal.tcf.dsf.services; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.ServiceDMContext; -import org.eclipse.dd.dsf.debug.service.INativeProcesses; -import org.eclipse.dd.dsf.service.AbstractDsfService; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.tm.internal.tcf.dsf.Activator; -import org.eclipse.tm.tcf.protocol.IChannel; -import org.eclipse.tm.tcf.protocol.IToken; -import org.eclipse.tm.tcf.services.IProcesses; -import org.eclipse.tm.tcf.services.IRunControl; -import org.eclipse.tm.tcf.services.IProcesses.ProcessContext; -import org.eclipse.tm.tcf.services.IRunControl.RunControlContext; -import org.osgi.framework.BundleContext; - - -public class TCFDSFNativeProcesses extends AbstractDsfService implements INativeProcesses { - - private class ProcessDMC extends TCFDSFProcessDMC implements IProcessDMContext { - - final String id; - - ProcessDMC(String id, IDMContext parent) { - super(TCFDSFNativeProcesses.this, parent != null ? new IDMContext[]{ parent } : new IDMContext[0]); - this.id = id; - } - - @Override - public String toString() { - return baseToString() + ".context[" + id + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - @Override - public boolean equals(Object obj) { - if (!super.baseEquals(obj)) return false; - String obj_id = ((ProcessDMC)obj).id; - if (obj_id == null) return id == null; - return obj_id.equals(id); - } - - @Override - public int hashCode() { - if (id == null) return 0; - return id.hashCode(); - } - } - - private class ThreadDMC extends TCFDSFThreadDMC implements IThreadDMContext { - - final String id; - - ThreadDMC(String id) { - super(TCFDSFNativeProcesses.this, new IDMContext[0]); - this.id = id; - } - - @Override - public String toString() { - return baseToString() + ".context[" + id + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - } - - @Override - public boolean equals(Object obj) { - if (!super.baseEquals(obj)) return false; - String obj_id = ((ThreadDMC)obj).id; - if (obj_id == null) return id == null; - return obj_id.equals(id); - } - - @Override - public int hashCode() { - return id.hashCode(); - } - } - - private class ProcessData implements IProcessDMData { - - private final IProcesses.ProcessContext ctx; - - ProcessData(IProcesses.ProcessContext ctx) { - this.ctx = ctx; - } - - public IDMContext getDebugContext() { - return getServicesTracker().getService(TCFDSFRunControl.class).getContext(ctx.getID()); - } - - public String getId() { - return ctx.getID(); - } - - public String getName() { - return ctx.getName(); - } - - public boolean isDebuggerAttached() { - return ctx.isAttached(); - } - - public boolean isValid() { - return true; - } - } - - private class ThreadData implements IThreadDMData { - - private final TCFDSFExecutionDMC ctx; - - ThreadData(TCFDSFExecutionDMC ctx) { - this.ctx = ctx; - } - - public IDMContext getDebugContext() { - return ctx; - } - - public String getId() { - if (ctx == null) return null; - return ctx.getTcfContextId(); - } - - public String getName() { - // TODO thread name - return ""; - } - - public boolean isDebuggerAttached() { - return true; - } - - public boolean isValid() { - return true; - } - } - - private class ProcessStartedEvent extends AbstractDMEvent<IDMContext> implements IProcessStartedEvent { - - private final IProcessDMContext prs; - - ProcessStartedEvent(IDMContext dmc, IProcessDMContext prs) { - super(dmc); - this.prs = prs; - } - - public IProcessDMContext getProcess() { - return prs; - } - } - - private class ProcessExitedEvent extends AbstractDMEvent<IDMContext> implements IProcessExitedEvent { - - private final IProcessDMContext prs; - - ProcessExitedEvent(IDMContext dmc, IProcessDMContext prs) { - super(dmc); - this.prs = prs; - } - - public IProcessDMContext getProcess() { - return prs; - } - } - - private final org.eclipse.tm.tcf.services.IRunControl.RunControlListener run_listener = - new org.eclipse.tm.tcf.services.IRunControl.RunControlListener() { - - public void containerResumed(String[] context_ids) { - } - - public void containerSuspended(String context, String pc, - String reason, Map<String, Object> params, - String[] suspended_ids) { - } - - public void contextAdded(RunControlContext[] contexts) { - for (RunControlContext ctx : contexts) { - String id = ctx.getID(); - if (id.equals(ctx.getProperties().get(IRunControl.PROP_PROCESS_ID))) { - ProcessDMC dmc = new ProcessDMC(id, root_dmc); - process_cache.put(id, dmc); - getSession().dispatchEvent(new ProcessStartedEvent(root_dmc, dmc), getProperties()); - } - else { - ThreadDMC dmc = new ThreadDMC(id); - thread_cache.put(id, dmc); - } - } - } - - public void contextChanged(RunControlContext[] contexts) { - } - - public void contextException(String context, String msg) { - } - - public void contextRemoved(String[] context_ids) { - for (String id : context_ids) { - ProcessDMC dmc = process_cache.remove(id); - if (dmc != null) { - getSession().dispatchEvent(new ProcessExitedEvent(root_dmc, dmc), getProperties()); - } - else { - thread_cache.remove(id); - } - } - } - - public void contextResumed(String context) { - } - - public void contextSuspended(String context, String pc, - String reason, Map<String, Object> params) { - } - }; - - private final IProcesses tcf_prs_service; - private final org.eclipse.tm.tcf.services.IRunControl tcf_run_service; - private final Map<String,ProcessDMC> process_cache = new HashMap<String,ProcessDMC>(); // all attached processes - private final Map<String,ThreadDMC> thread_cache = new HashMap<String,ThreadDMC>(); // only some of attached threads - private final ProcessDMC root_dmc = new ProcessDMC(null, null); - private IDMContext service_dmc; - - public TCFDSFNativeProcesses(DsfSession session, IChannel channel, final RequestMonitor monitor) { - super(session); - tcf_prs_service = channel.getRemoteService(IProcesses.class); - tcf_run_service = channel.getRemoteService(org.eclipse.tm.tcf.services.IRunControl.class); - if (tcf_run_service != null) tcf_run_service.addListener(run_listener); - service_dmc = new ServiceDMContext(this, "#native_process"); - initialize(new RequestMonitor(getExecutor(), monitor) { - @Override - protected void handleOK() { - String[] class_names = { - INativeProcesses.class.getName(), - TCFDSFNativeProcesses.class.getName() - }; - register(class_names, new Hashtable<String,String>()); - monitor.done(); - } - }); - } - - @Override - public void initialize(final RequestMonitor monitor) { - final Collection<String> list = new ArrayList<String>(); - final Set<IToken> cmds = new HashSet<IToken>(); - final IProcesses.DoneGetChildren done = new IProcesses.DoneGetChildren() { - public void doneGetChildren(IToken token, Exception error, String[] context_ids) { - if (cmds.isEmpty()) return; - assert cmds.contains(token); - cmds.remove(token); - if (error != null) { - for (IToken t : cmds) t.cancel(); - cmds.clear(); - monitor.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$ - monitor.done(); - } - else { - for (String id : context_ids) { - list.add(id); - cmds.add(tcf_prs_service.getChildren(id, true, this)); - } - if (cmds.isEmpty()) { - for (String id : list) { - assert id != null; - if (process_cache.get(id) != null) continue; - process_cache.put(id, new ProcessDMC(id, root_dmc)); - } - process_cache.put(null, root_dmc); - TCFDSFNativeProcesses.super.initialize(monitor); - } - } - } - }; - cmds.add(tcf_prs_service.getChildren(null, true, done)); - } - - @Override - public void shutdown(RequestMonitor monitor) { - unregister(); - super.shutdown(monitor); - } - - @Override - protected BundleContext getBundleContext() { - return Activator.getBundleContext(); - } - - public IDMContext getServiceContext() { - return service_dmc; - } - - public boolean isValid() { - return true; - } - - public void attachDebuggerToProcess(IProcessDMContext ctx, final RequestMonitor rm) { - if (tcf_prs_service == null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Service not available", null)); //$NON-NLS-1$ - rm.done(); - } - else if (ctx instanceof ProcessDMC) { - final ProcessDMC p = (ProcessDMC)ctx; - tcf_prs_service.getContext(p.id, new IProcesses.DoneGetContext() { - public void doneGetContext(IToken token, Exception error, ProcessContext context) { - if (rm.isCanceled()) return; - if (error != null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Cannot read processs attributes", error)); //$NON-NLS-1$ - rm.done(); - } - else if (context == null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Invalid processs ID", error)); //$NON-NLS-1$ - rm.done(); - } - else { - context.attach(new IProcesses.DoneCommand() { - public void doneCommand(IToken token, Exception error) { - if (rm.isCanceled()) return; - if (error != null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Cannot attach a process", error)); //$NON-NLS-1$ - } - assert error != null || process_cache.get(p.id) != null; - rm.done(); - } - }); - } - } - }); - } - else { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } - } - - public void canTerminate(IDMContext ctx, final DataRequestMonitor<Boolean> rm) { - rm.setData(false); - if (tcf_prs_service == null) { - rm.done(); - } - else if (ctx instanceof ProcessDMC) { - ProcessDMC p = (ProcessDMC)ctx; - tcf_prs_service.getContext(p.id, new IProcesses.DoneGetContext() { - public void doneGetContext(IToken token, Exception error, ProcessContext context) { - if (rm.isCanceled()) return; - if (error != null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Cannot read processs attributes", error)); //$NON-NLS-1$ - } - else if (context == null) { - rm.setData(false); - } - else { - rm.setData(context.canTerminate()); - } - rm.done(); - } - }); - } - else { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } - } - - public void terminate(IDMContext ctx, final RequestMonitor rm) { - if (tcf_prs_service == null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Service not available", null)); //$NON-NLS-1$ - rm.done(); - } - else if (ctx instanceof ProcessDMC) { - ProcessDMC p = (ProcessDMC)ctx; - tcf_prs_service.getContext(p.id, new IProcesses.DoneGetContext() { - public void doneGetContext(IToken token, Exception error, ProcessContext context) { - if (rm.isCanceled()) return; - if (error != null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Cannot read processs attributes", error)); //$NON-NLS-1$ - rm.done(); - } - else if (context == null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Invalid processs ID", error)); //$NON-NLS-1$ - rm.done(); - } - else { - context.terminate(new IProcesses.DoneCommand() { - public void doneCommand(IToken token, Exception error) { - if (rm.isCanceled()) return; - if (error != null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Cannot terminate a process", error)); //$NON-NLS-1$ - } - rm.done(); - } - }); - } - } - }); - } - else { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } - } - - public void debugNewProcess(String file, final DataRequestMonitor<IProcessDMContext> rm) { - if (tcf_prs_service == null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Service not available", null)); //$NON-NLS-1$ - rm.done(); - } - else { - tcf_prs_service.start(null, file, null, null, true, new IProcesses.DoneStart() { - public void doneStart(IToken token, Exception error, ProcessContext process) { - if (error != null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Cannot start a process", error)); //$NON-NLS-1$ - } - else { - ProcessDMC dmc = process_cache.get(process.getID()); - assert dmc != null; - rm.setData(dmc); - } - rm.done(); - } - }); - } - } - - public void runNewProcess(String file, final DataRequestMonitor<IProcessDMContext> rm) { - if (tcf_prs_service == null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Service not available", null)); //$NON-NLS-1$ - rm.done(); - } - else { - tcf_prs_service.start(null, file, null, null, false, new IProcesses.DoneStart() { - public void doneStart(IToken token, Exception error, ProcessContext process) { - if (error != null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Cannot start a process", error)); //$NON-NLS-1$ - } - else { - assert process_cache.get(process.getID()) == null; - rm.setData(new ProcessDMC(process.getID(), root_dmc)); - } - rm.done(); - } - }); - } - } - - public IProcessDMContext getProcessForDebugContext(IDMContext ctx) { - if (ctx instanceof IProcessDMContext) { - return (IProcessDMContext)ctx; - } - if (ctx instanceof TCFDSFExecutionDMC) { - String id = ((TCFDSFExecutionDMC)ctx).getTcfContextId(); - return process_cache.get(id); - } - return null; - } - - public IThreadDMContext getThreadForDebugContext(IDMContext ctx) { - if (ctx instanceof IThreadDMContext) { - return (IThreadDMContext)ctx; - } - if (ctx instanceof TCFDSFExecutionDMC) { - String id = ((TCFDSFExecutionDMC)ctx).getTcfContextId(); - ThreadDMC dmc = thread_cache.get(id); - if (dmc == null) dmc = new ThreadDMC(id); - return dmc; - } - return null; - } - - public void getProcessesBeingDebugged(DataRequestMonitor<IProcessDMContext[]> rm) { - rm.setData(process_cache.values().toArray(new IProcessDMContext[process_cache.size()])); - rm.done(); - } - - public void getRunningProcesses(final DataRequestMonitor<IProcessDMContext[]> rm) { - final Collection<String> list = new ArrayList<String>(); - final Set<IToken> cmds = new HashSet<IToken>(); - final IProcesses.DoneGetChildren done = new IProcesses.DoneGetChildren() { - public void doneGetChildren(IToken token, Exception error, String[] context_ids) { - if (cmds.isEmpty()) return; - assert cmds.contains(token); - cmds.remove(token); - if (error != null) { - for (IToken t : cmds) t.cancel(); - cmds.clear(); - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$ - rm.done(); - } - else { - for (String id : context_ids) { - list.add(id); - cmds.add(tcf_prs_service.getChildren(id, false, this)); - } - if (cmds.isEmpty()) { - int cnt = 0; - IProcessDMContext[] data = new IProcessDMContext[list.size()]; - for (String id : list) { - assert id != null; - data[cnt] = process_cache.get(id); - if (data[cnt] == null) data[cnt] = new ProcessDMC(id, root_dmc); - cnt++; - } - rm.setData(data); - rm.done(); - } - } - } - }; - cmds.add(tcf_prs_service.getChildren(null, false, done)); - } - - @SuppressWarnings("unchecked") - public void getModelData(IDMContext dmc, final DataRequestMonitor<?> rm) { - if (dmc instanceof ProcessDMC) { - getProcessData((ProcessDMC)dmc, (DataRequestMonitor<IProcessDMData>)rm); - } - else if (dmc instanceof ThreadDMC) { - getThreadData((ThreadDMC)dmc, (DataRequestMonitor<IThreadDMData>)rm); - } - else if (dmc == service_dmc) { - ((DataRequestMonitor<TCFDSFNativeProcesses>)rm).setData(this); - rm.done(); - } - else { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } - } - - public void getProcessData(IProcessDMContext dmc, final DataRequestMonitor<IProcessDMData> rm) { - if (dmc instanceof ProcessDMC) { - tcf_prs_service.getContext(((ProcessDMC)dmc).id, new IProcesses.DoneGetContext() { - - @SuppressWarnings("unchecked") - public void doneGetContext(IToken token, Exception error, ProcessContext context) { - if (rm.isCanceled()) return; - if (error != null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Cannot read processs attributes", error)); //$NON-NLS-1$ - } - else if (context == null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Invalid processs ID", error)); //$NON-NLS-1$ - } - else { - rm.setData(new ProcessData(context)); - } - rm.done(); - } - }); - } - else { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } - } - - public void getThreadData(IThreadDMContext dmc, final DataRequestMonitor<IThreadDMData> rm) { - if (dmc instanceof ThreadDMC) { - String id = ((ThreadDMC)dmc).id; - TCFDSFRunControl rc = getServicesTracker().getService(TCFDSFRunControl.class); - rm.setData(new ThreadData(rc.getContext(id))); - rm.done(); - } - else { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } - } -} diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFProcessDMC.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFProcessDMC.java deleted file mode 100644 index 8dacf0692..000000000 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFProcessDMC.java +++ /dev/null @@ -1,23 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.tm.internal.tcf.dsf.services; - -import org.eclipse.dd.dsf.datamodel.AbstractDMContext; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.service.INativeProcesses.IProcessDMContext; -import org.eclipse.dd.dsf.service.IDsfService; - -public abstract class TCFDSFProcessDMC extends AbstractDMContext implements IProcessDMContext { - - TCFDSFProcessDMC(IDsfService service, IDMContext[] parents) { - super(service, parents); - } -} diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java index 3093dfeb6..76542cfc7 100644 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java @@ -26,6 +26,7 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.AbstractDMContext; import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; +import org.eclipse.dd.dsf.datamodel.CompositeDMContext; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; @@ -38,6 +39,7 @@ import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.IRegisters.DoneGet; import org.eclipse.tm.tcf.services.IRegisters.DoneSet; import org.eclipse.tm.tcf.services.IRegisters.NamedValue; +import org.eclipse.tm.tcf.util.TCFDataCache; import org.osgi.framework.BundleContext; @@ -46,7 +48,7 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d private class ObjectDMC extends AbstractDMContext implements IFormattedDataDMContext { final String id; - final RegistersCache children; + final RegisterChildrenCache children; final Map<String,ValueDMC> values; org.eclipse.tm.tcf.services.IRegisters.RegistersContext context; @@ -55,12 +57,12 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d ObjectDMC(String session_id, IDMContext[] parents, String id) { super(session_id, parents); this.id = id; - children = new RegistersCache(channel, id, new IDMContext[]{ this }); + children = new RegisterChildrenCache(channel, id, new IDMContext[]{ this }); values = new HashMap<String,ValueDMC>(); model.put(id, this); } - ObjectDMC(String session_id, IDMContext[] parents, String id, RegistersCache children) { + ObjectDMC(String session_id, IDMContext[] parents, String id, RegisterChildrenCache children) { super(session_id, parents); this.id = id; this.children = children; @@ -98,7 +100,7 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d } /* Constructor for a fake register group - DSF requires at least one group object */ - RegisterGroupDMC(String session_id, IDMContext[] parents, final String id, RegistersCache children) { + RegisterGroupDMC(String session_id, IDMContext[] parents, final String id, RegisterChildrenCache children) { super(session_id, parents, id, children); context = new org.eclipse.tm.tcf.services.IRegisters.RegistersContext() { public int[] getBitNumbers() { @@ -367,23 +369,22 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d } } - private class RegistersCache extends TCFDataCache<Map<String,ObjectDMC>> - implements TCFDSFExecutionDMC.DataCache { + private class RegisterChildrenCache extends TCFDataCache<Map<String,ObjectDMC>> { final String id; final IDMContext[] parents; + Map<String,ObjectDMC> dmc_pool = new HashMap<String,ObjectDMC>();; boolean disposed; - public RegistersCache(IChannel channel, String id, IDMContext[] parents) { + public RegisterChildrenCache(IChannel channel, String id, IDMContext[] parents) { super(channel); this.id = id; this.parents = parents; } void invalidateRegContents() { - if (data == null) return; - for (ObjectDMC dmc : data.values()) { + for (ObjectDMC dmc : dmc_pool.values()) { for (ValueDMC val : dmc.values.values()) val.cache.reset(); dmc.children.invalidateRegContents(); } @@ -391,10 +392,9 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d void dispose() { assert !disposed; - if (data != null) { - for (ObjectDMC dmc : data.values()) dmc.dispose(); - } reset(); + for (ObjectDMC dmc : dmc_pool.values()) dmc.dispose(); + dmc_pool.clear(); disposed = true; } @@ -403,72 +403,56 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d assert command == null; assert !disposed; if (tcf_reg_service == null) { - data = null; - valid = true; + reset(null); return true; } command = tcf_reg_service.getChildren(id, new org.eclipse.tm.tcf.services.IRegisters.DoneGetChildren() { public void doneGetChildren(IToken token, Exception err, String[] contexts) { if (command != token) return; - command = null; - if (err != null) { - data = null; - error = err; + final LinkedHashMap<String,ObjectDMC> data = new LinkedHashMap<String,ObjectDMC>(); + if (err != null || contexts == null || contexts.length == 0) { + set(token, err, data); + return; } - else { - data = new LinkedHashMap<String,ObjectDMC>(); - if (contexts.length > 0) { - // TODO DSF service design does not support lazy retrieval of context attributes (because getName() is not async) - final Set<IToken> cmds = new HashSet<IToken>(); - final IToken cb = new IToken() { - public boolean cancel() { - for (IToken x : cmds) x.cancel(); - return false; + // TODO DSF service design does not support lazy retrieval of context attributes (because getName() is not async) + final Set<IToken> cmds = new HashSet<IToken>(); + final IToken cb = new IToken() { + public boolean cancel() { + for (IToken x : cmds) x.cancel(); + return false; + } + }; + command = cb; + org.eclipse.tm.tcf.services.IRegisters.DoneGetContext done = new org.eclipse.tm.tcf.services.IRegisters.DoneGetContext() { + public void doneGetContext(IToken token, Exception err, + org.eclipse.tm.tcf.services.IRegisters.RegistersContext context) { + cmds.remove(token); + if (command != cb) return; + if (err != null) { + command.cancel(); + set(cb, err, data); + return; + } + String id = context.getID(); + ObjectDMC dmc = model.get(id); + if (dmc == null) { + if (context.getBitNumbers() != null) { + dmc = new BitFieldDMC(getSession().getId(), parents, id); + } + else if (context.isReadable() || context.isWriteable()) { + dmc = new RegisterDMC(getSession().getId(), parents, id); } - }; - command = cb; - org.eclipse.tm.tcf.services.IRegisters.DoneGetContext done = new org.eclipse.tm.tcf.services.IRegisters.DoneGetContext() { - public void doneGetContext(IToken token, Exception err, - org.eclipse.tm.tcf.services.IRegisters.RegistersContext context) { - cmds.remove(token); - if (command != cb) return; - if (err != null) { - command.cancel(); - command = null; - data = null; - error = err; - valid = true; - validate(); - return; - } - String id = context.getID(); - ObjectDMC dmc = null; - if (context.getBitNumbers() != null) { - dmc = new BitFieldDMC(getSession().getId(), parents, id); - } - else if (context.isReadable() || context.isWriteable()) { - dmc = new RegisterDMC(getSession().getId(), parents, id); - } - else { - dmc = new RegisterGroupDMC(getSession().getId(), parents, id); - } - dmc.context = context; - data.put(id, dmc); - if (cmds.isEmpty()) { - command = null; - valid = true; - validate(); - } + else { + dmc = new RegisterGroupDMC(getSession().getId(), parents, id); } - }; - for (String id : contexts) { - cmds.add(tcf_reg_service.getContext(id, done)); } - return; + dmc_pool.put(id, dmc); + dmc.context = context; + data.put(id, dmc); + if (cmds.isEmpty()) set(cb, null, data); } - } - valid = true; - validate(); + }; + for (String id : contexts) cmds.add(tcf_reg_service.getContext(id, done)); } }); return false; @@ -498,12 +482,8 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d command = context.get(new org.eclipse.tm.tcf.services.IRegisters.DoneGet() { public void doneGet(IToken token, Exception err, byte[] value) { if (command != token) return; - command = null; - if (err != null) { - data = null; - error = err; - } - else { + FormattedValueDMData data = null; + if (value != null) { int radix = 10; if (fmt.equals(HEX_FORMAT)) radix = 16; else if (fmt.equals(OCTAL_FORMAT)) radix = 8; @@ -531,8 +511,7 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d } data = new FormattedValueDMData(s); } - valid = true; - validate(); + set(token, err, data); } }); return false; @@ -569,9 +548,7 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d } } - private static class GroupsChangedEvent - extends AbstractDMEvent<org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext> - implements IGroupsChangedDMEvent { + private static class GroupsChangedEvent extends AbstractDMEvent<IDMContext> implements IGroupsChangedDMEvent { public GroupsChangedEvent(IExecutionDMContext context) { super(context); @@ -584,7 +561,7 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d public void contextChanged() { TCFDSFRunControl rc = getServicesTracker().getService(TCFDSFRunControl.class); for (TCFDSFExecutionDMC dmc : rc.getCachedContexts()) { - RegistersCache c = (RegistersCache)dmc.registers_cache; + RegisterChildrenCache c = (RegisterChildrenCache)dmc.registers_cache; if (c != null) { c.dispose(); dmc.registers_cache = null; @@ -629,7 +606,7 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d if (tcf_reg_service != null) tcf_reg_service.addListener(listener); initialize(new RequestMonitor(getExecutor(), monitor) { @Override - protected void handleOK() { + protected void handleSuccess() { String[] class_names = { org.eclipse.dd.dsf.debug.service.IRegisters.class.getName(), TCFDSFRegisters.class.getName() @@ -715,10 +692,17 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d } rm.done(); } - - public void getRegisterGroups(final IDMContext dmc, final DataRequestMonitor<IRegisterGroupDMContext[]> rm) { - if (rm.isCanceled()) return; - RegistersCache cache = null; + + private RegisterChildrenCache getRegisterChildrenCache(IDMContext dmc, DataRequestMonitor<?> rm) { + RegisterChildrenCache cache = null; + if (dmc instanceof CompositeDMContext) { + for (IDMContext ctx : dmc.getParents()) { + if (ctx instanceof TCFDSFExecutionDMC || ctx instanceof TCFDSFStack.TCFFrameDMC) { + dmc = ctx; + break; + } + } + } if (tcf_reg_service == null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$ @@ -726,32 +710,38 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d else if (dmc instanceof TCFDSFExecutionDMC) { TCFDSFExecutionDMC exe = (TCFDSFExecutionDMC)dmc; if (exe.registers_cache == null) exe.registers_cache = - new RegistersCache(channel, exe.getTcfContextId(), new IDMContext[]{ exe }); - cache = (RegistersCache)exe.registers_cache; + new RegisterChildrenCache(channel, exe.getTcfContextId(), new IDMContext[]{ exe }); + cache = (RegisterChildrenCache)exe.registers_cache; } else if (dmc instanceof ObjectDMC) { if (((ObjectDMC)dmc).disposed) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$ - rm.done(); - return; } - cache = ((ObjectDMC)dmc).children; + else { + cache = ((ObjectDMC)dmc).children; + } + } + else if (dmc instanceof TCFDSFStack.TCFFrameDMC && ((TCFDSFStack.TCFFrameDMC)dmc).level == 0) { + TCFDSFExecutionDMC exe = ((TCFDSFStack.TCFFrameDMC)dmc).exe_dmc; + if (exe.registers_cache == null) exe.registers_cache = + new RegisterChildrenCache(channel, exe.getTcfContextId(), new IDMContext[]{ exe }); + cache = (RegisterChildrenCache)exe.registers_cache; } else { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ } + return cache; + } + + public void getRegisterGroups(final IDMContext dmc, final DataRequestMonitor<IRegisterGroupDMContext[]> rm) { + if (rm.isCanceled()) return; + RegisterChildrenCache cache = getRegisterChildrenCache(dmc, rm); if (cache != null) { if (!cache.validate()) { - cache.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { + cache.wait(new Runnable() { + public void run() { getRegisterGroups(dmc, rm); } }); @@ -768,20 +758,12 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d for (IDMContext x : c.values()) { if (x instanceof RegisterGroupDMC) cnt++; } - if (cnt == 0 && c.size() > 0 && dmc instanceof TCFDSFExecutionDMC) { - // TODO DSF requires at least one group - RegisterGroupDMC[] arr = new RegisterGroupDMC[1]; - arr[0] = new RegisterGroupDMC(getSession().getId(), cache.parents, cache.id, cache); - rm.setData(arr); - } - else { - RegisterGroupDMC[] arr = new RegisterGroupDMC[cnt]; - cnt = 0; - for (IDMContext x : c.values()) { - if (x instanceof RegisterGroupDMC) arr[cnt++] = (RegisterGroupDMC)x; - } - rm.setData(arr); + RegisterGroupDMC[] arr = new RegisterGroupDMC[cnt]; + cnt = 0; + for (IDMContext x : c.values()) { + if (x instanceof RegisterGroupDMC) arr[cnt++] = (RegisterGroupDMC)x; } + rm.setData(arr); } rm.done(); } @@ -792,40 +774,11 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d public void getRegisters(final IDMContext dmc, final DataRequestMonitor<IRegisterDMContext[]> rm) { if (rm.isCanceled()) return; - RegistersCache cache = null; - if (tcf_reg_service == null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$ - } - else if (dmc instanceof TCFDSFExecutionDMC) { - TCFDSFExecutionDMC exe = (TCFDSFExecutionDMC)dmc; - if (exe.registers_cache == null) exe.registers_cache = - new RegistersCache(channel, exe.getTcfContextId(), new IDMContext[]{ exe }); - cache = (RegistersCache)exe.registers_cache; - } - else if (dmc instanceof ObjectDMC) { - if (((ObjectDMC)dmc).disposed) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$ - rm.done(); - return; - } - cache = ((ObjectDMC)dmc).children; - } - else { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - } + RegisterChildrenCache cache = getRegisterChildrenCache(dmc, rm); if (cache != null) { if (!cache.validate()) { - cache.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { + cache.wait(new Runnable() { + public void run() { getRegisters(dmc, rm); } }); @@ -854,27 +807,11 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d public void getBitFields(final IDMContext dmc, final DataRequestMonitor<IBitFieldDMContext[]> rm) { if (rm.isCanceled()) return; - if (tcf_reg_service == null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$ - } - else if (dmc instanceof ObjectDMC) { - if (((ObjectDMC)dmc).disposed) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$ - rm.done(); - return; - } - RegistersCache cache = ((ObjectDMC)dmc).children; + RegisterChildrenCache cache = getRegisterChildrenCache(dmc, rm); + if (cache != null) { if (!cache.validate()) { - cache.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { + cache.wait(new Runnable() { + public void run() { getBitFields(dmc, rm); } }); @@ -898,17 +835,119 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d } rm.setData(arr); } - else { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + + public void findBitField(final IDMContext dmc, final String name, final DataRequestMonitor<IBitFieldDMContext> rm) { + if (rm.isCanceled()) return; + RegisterChildrenCache cache = getRegisterChildrenCache(dmc, rm); + if (cache != null) { + if (!cache.validate()) { + cache.wait(new Runnable() { + public void run() { + findBitField(dmc, name, rm); + } + }); + return; + } + if (cache.getError() != null) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$ + rm.done(); + return; + } + Map<String,ObjectDMC> c = cache.getData(); + BitFieldDMC res = null; + for (IDMContext x : c.values()) { + if (x instanceof BitFieldDMC) { + if (((BitFieldDMC)x).getName().equals(name)) { + res = (BitFieldDMC)x; + break; + } + } + } + if (res != null) rm.setData(res); + else rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Not found", null)); //$NON-NLS-1$ + } + rm.done(); + } + + public void findRegister(final IDMContext dmc, final String name, final DataRequestMonitor<IRegisterDMContext> rm) { + if (rm.isCanceled()) return; + RegisterChildrenCache cache = getRegisterChildrenCache(dmc, rm); + if (cache != null) { + if (!cache.validate()) { + cache.wait(new Runnable() { + public void run() { + findRegister(dmc, name, rm); + } + }); + return; + } + if (cache.getError() != null) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$ + rm.done(); + return; + } + Map<String,ObjectDMC> c = cache.getData(); + RegisterDMC res = null; + for (IDMContext x : c.values()) { + if (x instanceof RegisterDMC) { + if (((RegisterDMC)x).getName().equals(name)) { + res = (RegisterDMC)x; + break; + } + } + } + if (res != null) rm.setData(res); + else rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Not found", null)); //$NON-NLS-1$ + } + rm.done(); + } + + public void findRegisterGroup(final IDMContext dmc, final String name, final DataRequestMonitor<IRegisterGroupDMContext> rm) { + if (rm.isCanceled()) return; + RegisterChildrenCache cache = getRegisterChildrenCache(dmc, rm); + if (cache != null) { + if (!cache.validate()) { + cache.wait(new Runnable() { + public void run() { + findRegisterGroup(dmc, name, rm); + } + }); + return; + } + if (cache.getError() != null) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$ + rm.done(); + return; + } + Map<String,ObjectDMC> c = cache.getData(); + RegisterGroupDMC res = null; + for (IDMContext x : c.values()) { + if (x instanceof RegisterGroupDMC) { + if (((RegisterGroupDMC)x).getName().equals(name)) { + res = (RegisterGroupDMC)x; + break; + } + } + } + if (res != null) rm.setData(res); + else rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Not found", null)); //$NON-NLS-1$ } rm.done(); } - public void writeBitField(IDMContext dmc, String val, String fmt, final RequestMonitor rm) { + public void writeBitField(IBitFieldDMContext dmc, String val, String fmt, final RequestMonitor rm) { if (tcf_reg_service == null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$ + rm.done(); } else if (dmc instanceof ObjectDMC) { if (((ObjectDMC)dmc).disposed) { @@ -938,16 +977,15 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d rm.done(); } }); - return; } else { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); } - rm.done(); } - public void writeBitField(IDMContext dmc, IMnemonic mnemonic, final RequestMonitor rm) { + public void writeBitField(IBitFieldDMContext dmc, IMnemonic mnemonic, final RequestMonitor rm) { if (tcf_reg_service == null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$ @@ -988,8 +1026,46 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d rm.done(); } - public void writeRegister(IDMContext dmc, String val, String fmt, RequestMonitor rm) { - writeBitField(dmc, val, fmt, rm); + public void writeRegister(IRegisterDMContext dmc, String val, String fmt, final RequestMonitor rm) { + if (tcf_reg_service == null) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + INVALID_HANDLE, "Registers service is not available", null)); //$NON-NLS-1$ + rm.done(); + } + else if (dmc instanceof ObjectDMC) { + if (((ObjectDMC)dmc).disposed) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$ + rm.done(); + return; + } + int radix = 10; + if (fmt.equals(HEX_FORMAT)) radix = 16; + else if (fmt.equals(OCTAL_FORMAT)) radix = 8; + byte[] data = new BigInteger(val, radix).toByteArray(); + if (!((ObjectDMC)dmc).context.isBigEndian()) { + byte[] temp = new byte[data.length]; + for (int i = 0; i < data.length; i++) { + temp[temp.length - i - 1] = data[i]; + } + data = temp; + } + ((ObjectDMC)dmc).context.set(data, new org.eclipse.tm.tcf.services.IRegisters.DoneSet() { + public void doneSet(IToken token, Exception error) { + if (rm.isCanceled()) return; + if (error != null) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$ + } + rm.done(); + } + }); + } + else { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } } public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm) { @@ -1009,14 +1085,8 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d return; } if (!vmc.cache.validate()) { - vmc.cache.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { + vmc.cache.wait(new Runnable() { + public void run() { getFormattedExpressionValue(dmc, rm); } }); @@ -1073,20 +1143,20 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d @DsfServiceEventHandler public void eventDispatched(org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent e) { if (e.getReason() != StateChangeReason.STEP) { - RegistersCache cache = (RegistersCache)((TCFDSFExecutionDMC)e.getDMContext()).registers_cache; + RegisterChildrenCache cache = (RegisterChildrenCache)((TCFDSFExecutionDMC)e.getDMContext()).registers_cache; if (cache != null) cache.invalidateRegContents(); } } @DsfServiceEventHandler public void eventDispatched(org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent e) { - RegistersCache cache = (RegistersCache)((TCFDSFExecutionDMC)e.getDMContext()).registers_cache; + RegisterChildrenCache cache = (RegisterChildrenCache)((TCFDSFExecutionDMC)e.getDMContext()).registers_cache; if (cache != null) cache.invalidateRegContents(); } @DsfServiceEventHandler public void eventDispatched(org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent e) { - RegistersCache cache = (RegistersCache)((TCFDSFExecutionDMC)e.getExecutionContext()).registers_cache; + RegisterChildrenCache cache = (RegisterChildrenCache)((TCFDSFExecutionDMC)e.getDMContext()).registers_cache; if (cache != null) cache.dispose(); } } diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRunControl.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRunControl.java index 0cbe78a87..b3309a77c 100644 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRunControl.java +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRunControl.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.tm.internal.tcf.dsf.services; -import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -25,11 +24,11 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.ServiceDMContext; import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.model.IMemoryBlockRetrieval; import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension; import org.eclipse.tm.internal.tcf.debug.model.ITCFConstants; @@ -38,6 +37,7 @@ import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.IRunControl; import org.eclipse.tm.tcf.services.IRunControl.RunControlContext; +import org.eclipse.tm.tcf.util.TCFDataCache; import org.osgi.framework.BundleContext; @@ -79,37 +79,39 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. this.reason = toStateChangeReason(reason); } - public IExecutionDMContext getTriggeringContext() { - return cache.get(trigger_id); - } - public StateChangeReason getReason() { return reason; } + + public IExecutionDMContext[] getTriggeringContexts() { + IExecutionDMContext ctx = trigger_id == null ? null : cache.get(trigger_id); + return ctx == null ? new IExecutionDMContext[0] : new IExecutionDMContext[]{ ctx }; + } } - public static class ContainerResumedEvent extends AbstractDMEvent<IExecutionDMContext> implements IContainerResumedDMEvent { + public class ContainerResumedEvent extends AbstractDMEvent<IExecutionDMContext> implements IContainerResumedDMEvent { + + private final String trigger_id; - public ContainerResumedEvent(IExecutionDMContext dmc) { + public ContainerResumedEvent(IExecutionDMContext dmc, String trigger_id) { super(dmc); + this.trigger_id = trigger_id; } public StateChangeReason getReason() { return StateChangeReason.USER_REQUEST; } - } - public static class StartedEvent extends AbstractDMEvent<IContainerDMContext> implements IStartedDMEvent { + public IExecutionDMContext[] getTriggeringContexts() { + IExecutionDMContext ctx = trigger_id == null ? null : cache.get(trigger_id); + return ctx == null ? new IExecutionDMContext[0] : new IExecutionDMContext[]{ ctx }; + } + } - private final IExecutionDMContext exe; + public static class StartedEvent extends AbstractDMEvent<IExecutionDMContext> implements IStartedDMEvent { - public StartedEvent(IContainerDMContext dmc, IExecutionDMContext exe) { + public StartedEvent(IExecutionDMContext dmc) { super(dmc); - this.exe = exe; - } - - public IExecutionDMContext getExecutionContext() { - return exe; } } @@ -120,17 +122,10 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. } } - public static class ExitedEvent extends AbstractDMEvent<IContainerDMContext> implements IExitedDMEvent { - - private final IExecutionDMContext exe; + public static class ExitedEvent extends AbstractDMEvent<IExecutionDMContext> implements IExitedDMEvent { - public ExitedEvent(IContainerDMContext dmc, IExecutionDMContext exe) { + public ExitedEvent(IContainerDMContext dmc) { super(dmc); - this.exe = exe; - } - - public IExecutionDMContext getExecutionContext() { - return exe; } } @@ -144,10 +139,10 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. } for (String id : context_ids) { ExecutionDMC n = cache.get(id); - if (n != null && n.context.isValid()) { - RunControlContext c = n.context.getData(); + if (n != null && n.run_control_context_cache.isValid()) { + RunControlContext c = n.run_control_context_cache.getData(); if (c.isContainer()) { - getSession().dispatchEvent(new ContainerResumedEvent(n), getProperties()); + getSession().dispatchEvent(new ContainerResumedEvent(n, null), getProperties()); } } } @@ -167,8 +162,8 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. } for (String id : suspended_ids) { ExecutionDMC n = cache.get(id); - if (n != null && n.context.isValid()) { - RunControlContext c = n.context.getData(); + if (n != null && n.run_control_context_cache.isValid()) { + RunControlContext c = n.run_control_context_cache.getData(); if (c.isContainer()) { getSession().dispatchEvent(new ContainerSuspendedEvent(n, trigger_id, reason), getProperties()); } @@ -213,14 +208,6 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. } }; - private static class ExecutionState { - boolean is_suspended; - boolean is_running; - String suspend_pc; - String suspend_reason; - Map<String,Object> suspend_params; - } - private class ExecutionDMC extends TCFDSFExecutionDMC { final String id; @@ -231,125 +218,32 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. int is_stepping; int is_resuming; - final TCFDataCache<RunControlContext> context; - final TCFDataCache<Map<String,ExecutionDMC>> children; - final TCFDataCache<ExecutionState> state; - public ExecutionDMC(ExecutionDMC parent, final String id) { - super(TCFDSFRunControl.this, parent == null ? + super(channel, TCFDSFRunControl.this, parent == null ? new IDMContext[0] : new IDMContext[] { parent }); this.parent = parent; this.id = id; DsfMemoryBlockRetrieval mr = null; try { - mr = new DsfMemoryBlockRetrieval(ITCFConstants.ID_TCF_DEBUG_MODEL, this); + mr = new DsfMemoryBlockRetrieval(ITCFConstants.ID_TCF_DEBUG_MODEL, config, getSession()); } catch (DebugException e) { e.printStackTrace(); }; mem_retrieval = mr; - context = new TCFDataCache<RunControlContext>(channel) { - @Override - public boolean startDataRetrieval() { - assert command == null; - if (id == null || tcf_run_service == null) { - data = null; - valid = true; - return true; - } - command = tcf_run_service.getContext(id, new IRunControl.DoneGetContext() { - public void doneGetContext(IToken token, Exception err, IRunControl.RunControlContext ctx) { - if (command != token) return; - command = null; - if (err != null) { - error = err; - } - else { - data = ctx; - } - valid = true; - validate(); - } - }); - return false; - } - }; - children = new TCFDataCache<Map<String,ExecutionDMC>>(channel) { - @Override - public boolean startDataRetrieval() { - assert command == null; - if (tcf_run_service == null) { - data = null; - valid = true; - return true; - } - command = tcf_run_service.getChildren(id, new IRunControl.DoneGetChildren() { - public void doneGetChildren(IToken token, Exception err, String[] contexts) { - if (command != token) return; - command = null; - if (err != null) { - data = null; - error = err; - } - else { - if (data == null) data = new HashMap<String,ExecutionDMC>(); - data.clear(); - for (int i = 0; i < contexts.length; i++) { - String id = contexts[i]; - ExecutionDMC n = cache.get(id); - if (n == null) { - n = new ExecutionDMC(ExecutionDMC.this, id); - cache.put(n.id, n); - } - data.put(id, n); - } - } - valid = true; - validate(); - } - }); - return false; - } - }; - state = new TCFDataCache<ExecutionState>(channel) { - @Override - public boolean startDataRetrieval() { - assert command == null; - assert context.isValid(); - RunControlContext c = context.getData(); - if (c == null || !c.hasState()) { - data = null; - valid = true; - return true; - } - command = c.getState(new IRunControl.DoneGetState() { - public void doneGetState(IToken token, Exception err, boolean suspend, String pc, String reason, Map<String,Object> params) { - if (token != command) return; - command = null; - if (err != null) { - data = null; - error = err; - } - else { - data = new ExecutionState(); - data.is_running = !suspend; - data.is_suspended = suspend; - if (suspend) { - data.suspend_pc = pc; - data.suspend_reason = reason; - data.suspend_params = params; - } - } - valid = true; - validate(); - } - }); - return false; - } - }; } @Override + protected TCFDSFExecutionDMC addChild(String id) { + ExecutionDMC n = cache.get(id); + if (n == null) { + n = new ExecutionDMC(ExecutionDMC.this, id); + cache.put(id, n); + } + return n; + } + + @Override public String toString() { return baseToString() + ".context[" + id + "]"; //$NON-NLS-1$ //$NON-NLS-2$ } @@ -384,37 +278,20 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. } @Override - public void addStateWaitingRequest(IDataRequest req) { - state.addWaitingRequest(req); - } - - @Override - public TCFAddress getPC() { - ExecutionState st = state.getData(); - if (st == null) return null; - if (st.suspend_pc == null) return null; - return new TCFAddress(new BigInteger(st.suspend_pc)); - } - - @Override - public boolean validateState() { - return state.validate(); - } - - @Override public boolean isDisposed() { return disposed; } - void dispose() { + @Override + public void dispose() { assert !disposed; - context.cancel(); - children.cancel(); - state.cancel(); - if (children.isValid()) { - Map<String,ExecutionDMC> m = children.getData(); + run_control_context_cache.cancel(); + run_control_children_cache.cancel(); + run_control_state_cache.cancel(); + if (run_control_children_cache.isValid()) { + Map<String,TCFDSFExecutionDMC> m = run_control_children_cache.getData(); if (m != null) { - for (ExecutionDMC n : m.values()) n.dispose(); + for (TCFDSFExecutionDMC n : m.values()) n.dispose(); } } cache.remove(id); @@ -429,59 +306,59 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. assert !disposed; assert cache.get(id) == null; ExecutionDMC n = new ExecutionDMC(this, id); - n.context.reset(c); - if (children.isValid()) { - Map<String,ExecutionDMC> m = children.getData(); + n.run_control_context_cache.reset(c); + if (run_control_children_cache.isValid()) { + Map<String,TCFDSFExecutionDMC> m = run_control_children_cache.getData(); if (m != null) m.put(id, n); } cache.put(id, n); - getSession().dispatchEvent(new StartedEvent(this, n), getProperties()); + getSession().dispatchEvent(new StartedEvent(n), getProperties()); } void onContextChanged(IRunControl.RunControlContext c) { assert !disposed; - context.reset(c); + run_control_context_cache.reset(c); getSession().dispatchEvent(new ChangedEvent(this), getProperties()); } void onContextRemoved() { assert !disposed; - if (parent != null && parent.children.isValid()) { - Map<String,ExecutionDMC> m = parent.children.getData(); + if (parent != null && parent.run_control_children_cache.isValid()) { + Map<String,TCFDSFExecutionDMC> m = parent.run_control_children_cache.getData(); if (m != null) m.remove(id); } dispose(); - getSession().dispatchEvent(new ExitedEvent(parent, this), getProperties()); + getSession().dispatchEvent(new ExitedEvent(this), getProperties()); } void onContainerSuspended(String reason) { assert !disposed; - if (!context.isValid()) return; - RunControlContext rc = context.getData(); + if (!run_control_context_cache.isValid()) return; + RunControlContext rc = run_control_context_cache.getData(); if (rc == null) return; if (!rc.hasState()) return; - state.reset(); + run_control_state_cache.reset(); getSession().dispatchEvent(new SuspendedEvent(this, reason), getProperties()); } void onContextSuspended(String pc, String reason, Map<String,Object> params) { assert !disposed; - assert !context.isValid() || context.getData().hasState(); - ExecutionState st = new ExecutionState(); + assert !run_control_context_cache.isValid() || run_control_context_cache.getData().hasState(); + TCFDSFRunControlState st = new TCFDSFRunControlState(); st.is_suspended = true; st.suspend_pc = pc; st.suspend_reason = reason; st.suspend_params = params; - state.reset(st); + run_control_state_cache.reset(st); getSession().dispatchEvent(new SuspendedEvent(this, reason), getProperties()); } void onContextResumed() { assert !disposed; - assert !context.isValid() || context.getData().hasState(); - ExecutionState st = new ExecutionState(); + assert !run_control_context_cache.isValid() || run_control_context_cache.getData().hasState(); + TCFDSFRunControlState st = new TCFDSFRunControlState(); st.is_running = true; - state.reset(st); + run_control_state_cache.reset(st); getSession().dispatchEvent(new ResumedEvent(this), getProperties()); } @@ -522,23 +399,23 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. return StateChangeReason.UNKNOWN; } + private final ILaunchConfiguration config; private final IChannel channel; private final org.eclipse.tm.tcf.services.IRunControl tcf_run_service; private final Map<String,ExecutionDMC> cache = new HashMap<String,ExecutionDMC>(); private final ExecutionDMC root_dmc; - private IDMContext service_dmc; - public TCFDSFRunControl(DsfSession session, IChannel channel, final RequestMonitor monitor) { + public TCFDSFRunControl(ILaunchConfiguration config, DsfSession session, IChannel channel, final RequestMonitor monitor) { super(session); + this.config = config; this.channel = channel; tcf_run_service = channel.getRemoteService(org.eclipse.tm.tcf.services.IRunControl.class); if (tcf_run_service != null) tcf_run_service.addListener(run_listener); - service_dmc = new ServiceDMContext(this, "#run_control"); root_dmc = new ExecutionDMC(null, null); cache.put(null, root_dmc); initialize(new RequestMonitor(getExecutor(), monitor) { @Override - protected void handleOK() { + protected void handleSuccess() { String[] class_names = { org.eclipse.dd.dsf.debug.service.IRunControl.class.getName(), TCFDSFRunControl.class.getName() @@ -565,72 +442,56 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. public void getModelData(IDMContext dmc, final DataRequestMonitor<?> rm) { if (dmc instanceof ExecutionDMC) { final ExecutionDMC ctx = (ExecutionDMC)dmc; - if (!ctx.context.validate()) { - ctx.context.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { + if (!ctx.run_control_context_cache.validate()) { + ctx.run_control_context_cache.wait(new Runnable() { + public void run() { getModelData(ctx, rm); } }); return; } - if (ctx.context.getError() != null) { + if (ctx.run_control_context_cache.getError() != null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Data error", ctx.context.getError())); //$NON-NLS-1$ + REQUEST_FAILED, "Data error", ctx.run_control_context_cache.getError())); //$NON-NLS-1$ rm.done(); return; } - if (ctx.context.getData() == null) { + if (ctx.run_control_context_cache.getData() == null) { ExecutionData dt = new ExecutionData(StateChangeReason.UNKNOWN); ((DataRequestMonitor<IExecutionDMData>)rm).setData(dt); rm.done(); return; } - if (!ctx.context.getData().hasState()) { + if (!ctx.run_control_context_cache.getData().hasState()) { ExecutionData dt = new ExecutionData(StateChangeReason.UNKNOWN); ((DataRequestMonitor<IExecutionDMData>)rm).setData(dt); rm.done(); return; } - if (!ctx.state.validate()) { - ctx.state.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { + if (!ctx.run_control_state_cache.validate()) { + ctx.run_control_state_cache.wait(new Runnable() { + public void run() { getModelData(ctx, rm); } }); return; } - if (ctx.state.getError() != null) { + if (ctx.run_control_state_cache.getError() != null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Data error", ctx.state.getError())); //$NON-NLS-1$ + REQUEST_FAILED, "Data error", ctx.run_control_state_cache.getError())); //$NON-NLS-1$ rm.done(); return; } - if (ctx.state.getData() == null) { + if (ctx.run_control_state_cache.getData() == null) { ExecutionData dt = new ExecutionData(StateChangeReason.UNKNOWN); ((DataRequestMonitor<IExecutionDMData>)rm).setData(dt); rm.done(); return; } - ExecutionData dt = new ExecutionData(toStateChangeReason(ctx.state.getData().suspend_reason)); + ExecutionData dt = new ExecutionData(toStateChangeReason(ctx.run_control_state_cache.getData().suspend_reason)); ((DataRequestMonitor<IExecutionDMData>)rm).setData(dt); rm.done(); } - else if (dmc == service_dmc) { - ((DataRequestMonitor<TCFDSFRunControl>)rm).setData(this); - rm.done(); - } else { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ @@ -638,59 +499,74 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. } } - public IDMContext getServiceContext() { - return service_dmc; - } - public boolean isValid() { return true; } - public boolean canInstructionStep(IDMContext context) { + public void canResume(final IExecutionDMContext context, final DataRequestMonitor<Boolean> rm) { if (context instanceof ExecutionDMC) { ExecutionDMC ctx = (ExecutionDMC)context; - if (ctx.context.isValid()) { - RunControlContext c = ctx.context.getData(); - return c != null && c.canResume(org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO); + if (!ctx.run_control_context_cache.validate()) { + ctx.run_control_context_cache.wait(new Runnable() { + public void run() { + canResume(context, rm); + } + }); } - } - return false; - } - - public boolean canResume(IDMContext context) { - if (context instanceof ExecutionDMC) { - ExecutionDMC ctx = (ExecutionDMC)context; - if (ctx.context.isValid()) { - RunControlContext c = ctx.context.getData(); - return c != null && c.canResume(org.eclipse.tm.tcf.services.IRunControl.RM_RESUME); + else { + RunControlContext c = ctx.run_control_context_cache.getData(); + rm.setData(c != null && c.canResume(org.eclipse.tm.tcf.services.IRunControl.RM_RESUME)); + rm.done(); } } - return false; + else { + rm.setData(false); + rm.done(); + } } - public boolean canStep(IDMContext context) { + public void canStep(final IExecutionDMContext context, final StepType step_type, final DataRequestMonitor<Boolean> rm) { if (context instanceof ExecutionDMC) { ExecutionDMC ctx = (ExecutionDMC)context; - if (ctx.context.isValid()) { - RunControlContext c = ctx.context.getData(); - if (c != null) { - if (c.canResume(org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO_LINE)) return true; - if (c.canResume(org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO)) return true; - } + if (!ctx.run_control_context_cache.validate()) { + ctx.run_control_context_cache.wait(new Runnable() { + public void run() { + canStep(context, step_type, rm); + } + }); + } + else { + RunControlContext c = ctx.run_control_context_cache.getData(); + rm.setData(c != null && c.canResume(toTCFStepType(step_type))); + rm.done(); } } - return false; + else { + rm.setData(false); + rm.done(); + } } - public boolean canSuspend(IDMContext context) { + public void canSuspend(final IExecutionDMContext context, final DataRequestMonitor<Boolean> rm) { if (context instanceof ExecutionDMC) { ExecutionDMC ctx = (ExecutionDMC)context; - if (ctx.context.isValid()) { - RunControlContext c = ctx.context.getData(); - return c != null && c.canSuspend(); + if (!ctx.run_control_context_cache.validate()) { + ctx.run_control_context_cache.wait(new Runnable() { + public void run() { + canSuspend(context, rm); + } + }); + } + else { + RunControlContext c = ctx.run_control_context_cache.getData(); + rm.setData(c != null && c.canSuspend()); + rm.done(); } } - return false; + else { + rm.setData(false); + rm.done(); + } } public TCFDSFExecutionDMC getContext(String id) { @@ -698,29 +574,28 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. } public void getContainerContexts(IContainerDMContext context, final DataRequestMonitor<IExecutionDMContext[]> rm) { - getContexts(context, rm, false); + getContexts(context, rm, false, false); } public void getExecutionContexts(IContainerDMContext context, final DataRequestMonitor<IExecutionDMContext[]> rm) { - getContexts(context, rm, true); + getContexts(context, rm, false, true); + } + + public void getAllContexts(IContainerDMContext context, final DataRequestMonitor<IExecutionDMContext[]> rm) { + getContexts(context, rm, true, true); } public void getContexts(IContainerDMContext context, - final DataRequestMonitor<IExecutionDMContext[]> rm, final boolean has_state) { + final DataRequestMonitor<IExecutionDMContext[]> rm, + final boolean all, final boolean has_state) { if (context == null) context = root_dmc; if (context instanceof ExecutionDMC) { final ExecutionDMC ctx = (ExecutionDMC)context; - TCFDataCache<Map<String,ExecutionDMC>> cache = ctx.children; + TCFDataCache<Map<String,TCFDSFExecutionDMC>> cache = ctx.run_control_children_cache; if (!cache.validate()) { - cache.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { - getContexts(ctx, rm, has_state); + cache.wait(new Runnable() { + public void run() { + getContexts(ctx, rm, all, has_state); } }); return; @@ -736,40 +611,34 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. rm.done(); return; } - final Set<IDataRequest> reqs = new HashSet<IDataRequest>(); - for (ExecutionDMC e : cache.getData().values()) { - if (!e.context.validate()) { - IDataRequest req = new IDataRequest() { - public void cancel() { - if (reqs.remove(this) && reqs.isEmpty()) getContexts(ctx, rm, has_state); - } - public void done() { - if (reqs.remove(this) && reqs.isEmpty()) getContexts(ctx, rm, has_state); + final Set<Runnable> reqs = new HashSet<Runnable>(); + for (TCFDSFExecutionDMC e : cache.getData().values()) { + if (!e.run_control_context_cache.validate()) { + Runnable req = new Runnable() { + public void run() { + if (reqs.remove(this) && reqs.isEmpty()) getContexts(ctx, rm, all, has_state); } }; reqs.add(req); - e.context.addWaitingRequest(req); + e.run_control_context_cache.wait(req); } // TODO DSF service design does not support lazy retrieval of context state (because isSuspened() is not async) - else if (!e.state.validate()) { - IDataRequest req = new IDataRequest() { - public void cancel() { - if (reqs.remove(this) && reqs.isEmpty()) getContexts(ctx, rm, has_state); - } - public void done() { - if (reqs.remove(this) && reqs.isEmpty()) getContexts(ctx, rm, has_state); + else if (!e.run_control_state_cache.validate()) { + Runnable req = new Runnable() { + public void run() { + if (reqs.remove(this) && reqs.isEmpty()) getContexts(ctx, rm, all, has_state); } }; reqs.add(req); - e.state.addWaitingRequest(req); + e.run_control_state_cache.wait(req); } } if (reqs.isEmpty()) { - ArrayList<ExecutionDMC> l = new ArrayList<ExecutionDMC>(); - for (ExecutionDMC e : cache.getData().values()) { - assert e.context.isValid(); - RunControlContext c = e.context.getData(); - if (c.hasState() == has_state) l.add(e); + ArrayList<TCFDSFExecutionDMC> l = new ArrayList<TCFDSFExecutionDMC>(); + for (TCFDSFExecutionDMC e : cache.getData().values()) { + assert e.run_control_context_cache.isValid(); + RunControlContext c = e.run_control_context_cache.getData(); + if (all || has_state == c.hasState()) l.add(e); } rm.setData(l.toArray(new ExecutionDMC[l.size()])); rm.done(); @@ -787,91 +656,32 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. for (ExecutionDMC dmc : cache.values()) l.add(dmc); return l; } - - public void step(IDMContext context, StepType stepType, final RequestMonitor rm) { - if (context instanceof ExecutionDMC) { - final ExecutionDMC ctx = (ExecutionDMC)context; - if (ctx.context.isValid()) { - RunControlContext c = ctx.context.getData(); - if (c != null) { - int md = -1; - if (c.canResume(org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO_LINE)) { - switch (stepType) { - case STEP_OVER: - md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OVER_LINE; - break; - case STEP_INTO: - md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO_LINE; - break; - case STEP_RETURN: - md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OUT; - break; - } - } - else { - switch (stepType) { - case STEP_OVER: - md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OVER; - break; - case STEP_INTO: - md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO; - break; - case STEP_RETURN: - md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OUT; - break; - } - } - if (md < 0) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - NOT_SUPPORTED, "Invalid step type", null)); //$NON-NLS-1$ - rm.done(); - } - else { - c.resume(md, 1, new org.eclipse.tm.tcf.services.IRunControl.DoneCommand() { - public void doneCommand(IToken token, Exception error) { - if (rm.isCanceled()) return; - if (error != null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$ - } - ctx.is_stepping--; - rm.done(); - } - }); - ctx.is_stepping++; - } - return; - } - } - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$ - rm.done(); - } - else { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } - } - - public void instructionStep(IDMContext context, StepType stepType, final RequestMonitor rm) { + + public int toTCFStepType(StepType step_type) { + switch (step_type) { + case STEP_OVER: + return org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OVER_LINE; + case STEP_INTO: + return org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO_LINE; + case STEP_RETURN: + return org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OUT; + case INSTRUCTION_STEP_OVER: + return org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OVER; + case INSTRUCTION_STEP_INTO: + return org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO; + case INSTRUCTION_STEP_RETUTRN: + return org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OUT; + } + return -1; + } + + public void step(IExecutionDMContext context, StepType step_type, final RequestMonitor rm) { if (context instanceof ExecutionDMC) { final ExecutionDMC ctx = (ExecutionDMC)context; - if (ctx.context.isValid()) { - RunControlContext c = ctx.context.getData(); + if (ctx.run_control_context_cache.isValid()) { + RunControlContext c = ctx.run_control_context_cache.getData(); if (c != null) { - int md = -1; - switch (stepType) { - case STEP_OVER: - md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OVER; - break; - case STEP_INTO: - md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_INTO; - break; - case STEP_RETURN: - md = org.eclipse.tm.tcf.services.IRunControl.RM_STEP_OUT; - break; - } + int md = toTCFStepType(step_type); if (md < 0) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, NOT_SUPPORTED, "Invalid step type", null)); //$NON-NLS-1$ @@ -905,7 +715,7 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. } } - public boolean isStepping(IDMContext context) { + public boolean isStepping(IExecutionDMContext context) { if (context instanceof ExecutionDMC) { ExecutionDMC x = (ExecutionDMC)context; return x.is_stepping > 0; @@ -913,11 +723,11 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. return false; } - public void resume(IDMContext context, final RequestMonitor rm) { + public void resume(IExecutionDMContext context, final RequestMonitor rm) { if (context instanceof ExecutionDMC) { final ExecutionDMC ctx = (ExecutionDMC)context; - if (ctx.context.isValid()) { - RunControlContext c = ctx.context.getData(); + if (ctx.run_control_context_cache.isValid()) { + RunControlContext c = ctx.run_control_context_cache.getData(); if (c != null) { c.resume(org.eclipse.tm.tcf.services.IRunControl.RM_RESUME, 1, new org.eclipse.tm.tcf.services.IRunControl.DoneCommand() { @@ -946,11 +756,11 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. } } - public void suspend(IDMContext context, final RequestMonitor rm) { + public void suspend(IExecutionDMContext context, final RequestMonitor rm) { if (context instanceof ExecutionDMC) { final ExecutionDMC ctx = (ExecutionDMC)context; - if (ctx.context.isValid()) { - RunControlContext c = ctx.context.getData(); + if (ctx.run_control_context_cache.isValid()) { + RunControlContext c = ctx.run_control_context_cache.getData(); if (c != null) { c.suspend(new org.eclipse.tm.tcf.services.IRunControl.DoneCommand() { public void doneCommand(IToken token, Exception error) { @@ -976,38 +786,41 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. } } - public boolean isSuspended(IDMContext context) { + public boolean hasState(IExecutionDMContext context) { + boolean r = false; if (context instanceof ExecutionDMC) { ExecutionDMC ctx = (ExecutionDMC)context; - boolean r = false; - if (ctx.context.isValid()) { - RunControlContext c = ctx.context.getData(); + if (ctx.run_control_context_cache.isValid()) { + RunControlContext c = ctx.run_control_context_cache.getData(); + return c != null && c.hasState(); + } + } + return r; + } + + public boolean isSuspended(IExecutionDMContext context) { + boolean r = false; + if (context instanceof ExecutionDMC) { + ExecutionDMC ctx = (ExecutionDMC)context; + if (ctx.run_control_context_cache.isValid()) { + RunControlContext c = ctx.run_control_context_cache.getData(); if (c != null && c.hasState()) { - if (ctx.is_resuming == 0 && ctx.is_stepping == 0 && ctx.state.isValid()) { - ExecutionState st = ctx.state.getData(); + if (ctx.is_resuming == 0 && ctx.is_stepping == 0 && ctx.run_control_state_cache.isValid()) { + TCFDSFRunControlState st = ctx.run_control_state_cache.getData(); if (st != null) r = st.is_suspended; } } - else if (ctx.children.isValid()) { - Map<String,ExecutionDMC> m = ctx.children.getData(); - if (m != null) { - for (ExecutionDMC e : m.values()) { - if (isSuspended(e)) r = true; - } - } - } } - return r; } - return false; + return r; } public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor<IExecutionDMData> rm) { if (dmc instanceof ExecutionDMC) { ExecutionDMC ctx = (ExecutionDMC)dmc; StateChangeReason r = StateChangeReason.UNKNOWN; - if (ctx.state.isValid()) { - ExecutionState st = ctx.state.getData(); + if (ctx.run_control_state_cache.isValid()) { + TCFDSFRunControlState st = ctx.run_control_state_cache.getData(); if (st != null && st.suspend_reason != null) { r = toStateChangeReason(st.suspend_reason); } diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRunControlState.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRunControlState.java new file mode 100644 index 000000000..56ce4fd6e --- /dev/null +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRunControlState.java @@ -0,0 +1,19 @@ +package org.eclipse.tm.internal.tcf.dsf.services; + +import java.math.BigInteger; +import java.util.Map; + +public class TCFDSFRunControlState { + + public boolean is_suspended; + public boolean is_running; + public String suspend_pc; + public String suspend_reason; + public Map<String,Object> suspend_params; + + public TCFAddress getPC() { + if (suspend_pc == null) return null; + return new TCFAddress(new BigInteger(suspend_pc)); + } +} + diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java index 67f7c9461..bd2e3ef45 100644 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java @@ -23,7 +23,6 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.AbstractDMContext; import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.datamodel.ServiceDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl; import org.eclipse.dd.dsf.debug.service.IStack; import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; @@ -36,6 +35,7 @@ import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.services.ILineNumbers; import org.eclipse.tm.tcf.services.IStackTrace; import org.eclipse.tm.tcf.services.ILineNumbers.CodeArea; +import org.eclipse.tm.tcf.util.TCFDataCache; import org.osgi.framework.BundleContext; @@ -43,7 +43,7 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { private static final String TOP_FRAME = "TopFrame:"; - private class TCFFrameDMC extends AbstractDMContext implements IFrameDMContext, Comparable<TCFFrameDMC> { + class TCFFrameDMC extends AbstractDMContext implements IFrameDMContext, Comparable<TCFFrameDMC> { final String id; final TCFDSFExecutionDMC exe_dmc; @@ -62,8 +62,7 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { public boolean startDataRetrieval() { assert command == null; if (id == null || tcf_stk_service == null) { - data = null; - valid = true; + reset(null); return true; } if (level == 0) { @@ -75,31 +74,24 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { command = tcf_stk_service.getContext(new String[]{ id }, new IStackTrace.DoneGetContext() { public void doneGetContext(IToken token, Exception err, IStackTrace.StackTraceContext[] context) { if (command != token) return; - command = null; - if (err != null) { - error = err; - data = null; + TCFFrameData data = null; + TCFAddress a = null; + Number n = context[0].getReturnAddress(); + if (n != null) a = new TCFAddress(n); + // Optimization: skip source position lookup if same address + if (prev_data != null && prev_data.address != null && prev_data.address.equals(a)) { + data = prev_data; + data.context = context[0]; + data.level = level; } else { - TCFAddress a = null; - Number n = context[0].getReturnAddress(); - if (n != null) a = new TCFAddress(n); - // Optimization: skip source position lookup if same address - if (prev_data != null && prev_data.address.equals(a)) { - data = prev_data; - data.context = context[0]; - data.level = level; - } - else { - data = new TCFFrameData(); - data.context = context[0]; - data.address = a; - data.level = level; - if (!getSourcePos()) return; - } + data = new TCFFrameData(); + data.context = context[0]; + data.address = a; + data.level = level; + if (!getSourcePos(data)) return; } - valid = true; - validate(); + set(token, err, prev_data = data); } }); return false; @@ -107,48 +99,36 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { private boolean getTopFrame() { assert level == 0; - if (!exe_dmc.validateState()) { - exe_dmc.addStateWaitingRequest(new IDataRequest() { - public void cancel() { - reset(); - } - public void done() { - validate(); - } - }); + TCFDataCache<TCFDSFRunControlState> cache = exe_dmc.run_control_state_cache; + if (!cache.validate()) { + cache.wait(this); return false; } - prev_data = data = new TCFFrameData(); - data.address = exe_dmc.getPC(); + TCFFrameData data = new TCFFrameData(); + TCFDSFRunControlState state = cache.getData(); + if (state != null) data.address = state.getPC(); data.level = level; - if (!getSourcePos()) return false; - valid = true; + if (!getSourcePos(data)) return false; + reset(prev_data = data); return true; } - private boolean getSourcePos() { + private boolean getSourcePos(final TCFFrameData data) { if (tcf_lns_service == null) return true; if (data.address == null) return true; BigInteger a1 = data.address.getValue(); BigInteger a2 = data.address.add(1).getValue(); command = tcf_lns_service.mapToSource(exe_dmc.getTcfContextId(), a1, a2, new ILineNumbers.DoneMapToSource() { - public void doneMapToSource(IToken token, Exception err, CodeArea[] areas) { if (command != token) return; - command = null; - if (err != null) { - data.src_pos_error = err; - } - else if (areas != null && areas.length > 0) { + if (areas != null && areas.length > 0) { for (ILineNumbers.CodeArea area : areas) { if (data.code_area == null || area.start_line < data.code_area.start_line) { data.code_area = area; } } - prev_data = data; } - valid = true; - validate(); + set(token, err, prev_data = data); } }); return false; @@ -219,7 +199,7 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { } } - private class FramesCache extends TCFDataCache<Map<String,TCFFrameDMC>> implements TCFDSFExecutionDMC.DataCache { + private class FramesCache extends TCFDataCache<Map<String,TCFFrameDMC>> { private final TCFDSFExecutionDMC dmc; private final Map<String,TCFFrameDMC> frame_pool; @@ -234,21 +214,15 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { public boolean startDataRetrieval() { assert command == null; if (tcf_stk_service == null) { - data = null; - valid = true; + reset(null); return true; } assert !dmc.isDisposed(); command = tcf_stk_service.getChildren(dmc.getTcfContextId(), new IStackTrace.DoneGetChildren() { public void doneGetChildren(IToken token, Exception err, String[] contexts) { if (command != token) return; - command = null; - if (err != null) { - data = null; - error = err; - } - else { - data = new HashMap<String,TCFFrameDMC>(); + HashMap<String,TCFFrameDMC> data = new HashMap<String,TCFFrameDMC>(); + if (contexts != null) { for (int i = 0; i < contexts.length; i++) { String id = contexts[i]; TCFFrameDMC n = frame_pool.get(id); @@ -256,14 +230,13 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { n.level = contexts.length - i; data.put(id, n); } - String id = TOP_FRAME + dmc.getTcfContextId(); - TCFFrameDMC n = frame_pool.get(id); - if (n == null) frame_pool.put(id, n = new TCFFrameDMC(dmc, id)); - n.level = 0; - data.put(id, n); } - valid = true; - validate(); + String id = TOP_FRAME + dmc.getTcfContextId(); + TCFFrameDMC n = frame_pool.get(id); + if (n == null) frame_pool.put(id, n = new TCFFrameDMC(dmc, id)); + n.level = 0; + data.put(id, n); + set(token, err, data); } }); return false; @@ -281,17 +254,15 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { private final IChannel channel; private final IStackTrace tcf_stk_service; private final ILineNumbers tcf_lns_service; - private IDMContext service_dmc; public TCFDSFStack(DsfSession session, IChannel channel, final RequestMonitor monitor) { super(session); this.channel = channel; tcf_stk_service = channel.getRemoteService(IStackTrace.class); tcf_lns_service = channel.getRemoteService(ILineNumbers.class); - service_dmc = new ServiceDMContext(this, "#stack_trace"); initialize(new RequestMonitor(getExecutor(), monitor) { @Override - protected void handleOK() { + protected void handleSuccess() { String[] class_names = { IStack.class.getName(), TCFDSFStack.class.getName() @@ -315,11 +286,7 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { return Activator.getBundleContext(); } - public IDMContext getServiceContext() { - return service_dmc; - } - - public void getArguments(IDMContext dmc, DataRequestMonitor<IVariableDMContext[]> rm) { + public void getArguments(IFrameDMContext dmc, DataRequestMonitor<IVariableDMContext[]> rm) { if (dmc instanceof TCFFrameDMC) { // TODO function arguments rm.setData(new IVariableDMContext[0]); @@ -337,14 +304,8 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { final TCFFrameDMC frame_dmc = (TCFFrameDMC)dmc; TCFDataCache<TCFFrameData> cache = frame_dmc.frame_data; if (!cache.validate()) { - cache.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { + cache.wait(new Runnable() { + public void run() { getFrameData(dmc, rm); } }); @@ -366,31 +327,57 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { } } - public void getFrames(final IDMContext dmc, final DataRequestMonitor<IFrameDMContext[]> rm) { + private TCFDataCache<?> createFramesCache(TCFDSFExecutionDMC exe, DataRequestMonitor<?> rm) { if (tcf_stk_service == null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, INVALID_HANDLE, "Stack trace service is not available", null)); //$NON-NLS-1$ rm.done(); + return null; + } + if (exe.isDisposed()) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$ + rm.done(); + return null; + } + if (!exe.run_control_context_cache.validate()) { + return exe.run_control_context_cache; + } + if (exe.run_control_context_cache.getError() != null) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Data error", exe.run_control_context_cache.getError())); //$NON-NLS-1$ + rm.done(); + return null; } - else if (dmc instanceof TCFDSFExecutionDMC) { + org.eclipse.tm.tcf.services.IRunControl.RunControlContext ctx = exe.run_control_context_cache.getData(); + if (ctx == null || !ctx.hasState()) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + INVALID_HANDLE, "DMC does not have a stack", null)); //$NON-NLS-1$ + rm.done(); + return null; + } + if (exe.stack_frames_cache == null) exe.stack_frames_cache = new FramesCache(channel, exe); + return exe.stack_frames_cache; + + } + + public void getFrames(final IDMContext dmc, final DataRequestMonitor<IFrameDMContext[]> rm) { + if (dmc instanceof TCFDSFExecutionDMC) { TCFDSFExecutionDMC exe = (TCFDSFExecutionDMC)dmc; - if (exe.isDisposed()) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$ - rm.done(); + TCFDataCache<?> cache0 = createFramesCache(exe, rm); + if (cache0 == null) return; + if (cache0 != exe.stack_frames_cache) { + cache0.wait(new Runnable() { + public void run() { + getFrames(dmc, rm); + } + }); return; } - if (exe.stack_frames_cache == null) exe.stack_frames_cache = new FramesCache(channel, exe); - FramesCache cache = (FramesCache)exe.stack_frames_cache; + FramesCache cache = (FramesCache)cache0; if (!cache.validate()) { - cache.addWaitingRequest(new IDataRequest() { - public void cancel() { - rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID, - REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$ - rm.setCanceled(true); - rm.done(); - } - public void done() { + cache.wait(new Runnable() { + public void run() { getFrames(dmc, rm); } }); @@ -402,8 +389,8 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { rm.done(); return; } - Map<String,TCFFrameDMC> c = cache.getData(); - TCFFrameDMC[] arr = c.values().toArray(new TCFFrameDMC[c.size()]); + Map<String,TCFFrameDMC> map = cache.getData(); + TCFFrameDMC[] arr = map.values().toArray(new TCFFrameDMC[map.size()]); Arrays.sort(arr); rm.setData(arr); rm.done(); @@ -415,7 +402,7 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { } } - public void getLocals(IDMContext dmc, DataRequestMonitor<IVariableDMContext[]> rm) { + public void getLocals(IFrameDMContext dmc, DataRequestMonitor<IVariableDMContext[]> rm) { if (dmc instanceof TCFFrameDMC) { // TODO function local variables rm.setData(new IVariableDMContext[0]); @@ -428,31 +415,58 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { } } - public void getStackDepth(DataRequestMonitor<Integer> rm) { - // TODO don't know what getStackDepth() is supposed to return - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } - - public void getStackDepth(int maxDepth, DataRequestMonitor<Integer> rm) { - // TODO don't know what getStackDepth() is supposed to return - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } - - public void getTopFrame(IDMContext dmc, DataRequestMonitor<IFrameDMContext> rm) { + public void getStackDepth(final IDMContext dmc, final int maxDepth, final DataRequestMonitor<Integer> rm) { if (dmc instanceof TCFDSFExecutionDMC) { TCFDSFExecutionDMC exe = (TCFDSFExecutionDMC)dmc; - if (exe.isDisposed()) { + TCFDataCache<?> cache0 = createFramesCache(exe, rm); + if (cache0 == null) return; + if (cache0 != exe.stack_frames_cache) { + cache0.wait(new Runnable() { + public void run() { + getStackDepth(dmc, maxDepth, rm); + } + }); + return; + } + FramesCache cache = (FramesCache)cache0; + if (!cache.validate()) { + cache.wait(new Runnable() { + public void run() { + getStackDepth(dmc, maxDepth, rm); + } + }); + return; + } + if (cache.getError() != null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$ + REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$ rm.done(); return; } - if (exe.stack_frames_cache == null) exe.stack_frames_cache = new FramesCache(channel, exe); - FramesCache cache = (FramesCache)exe.stack_frames_cache; + rm.setData(cache.getData().size()); + rm.done(); + } + else { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ + rm.done(); + } + } + + public void getTopFrame(final IDMContext dmc, final DataRequestMonitor<IFrameDMContext> rm) { + if (dmc instanceof TCFDSFExecutionDMC) { + TCFDSFExecutionDMC exe = (TCFDSFExecutionDMC)dmc; + TCFDataCache<?> cache0 = createFramesCache(exe, rm); + if (cache0 == null) return; + if (cache0 != exe.stack_frames_cache) { + cache0.wait(new Runnable() { + public void run() { + getTopFrame(dmc, rm); + } + }); + return; + } + FramesCache cache = (FramesCache)cache0; String id = TOP_FRAME + exe.getTcfContextId(); TCFFrameDMC n = cache.frame_pool.get(id); if (n == null) cache.frame_pool.put(id, n = new TCFFrameDMC(exe, id)); @@ -483,10 +497,6 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { if (dmc instanceof IFrameDMContext) { getFrameData((IFrameDMContext)dmc, (DataRequestMonitor<IFrameDMData>)rm); } - else if (dmc == service_dmc) { - ((DataRequestMonitor<TCFDSFStack>)rm).setData(this); - rm.done(); - } else { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ @@ -510,7 +520,7 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { @DsfServiceEventHandler public void eventDispatched(IRunControl.IExitedDMEvent e) { - FramesCache cache = (FramesCache)((TCFDSFExecutionDMC)e.getExecutionContext()).stack_frames_cache; + FramesCache cache = (FramesCache)((TCFDSFExecutionDMC)e.getDMContext()).stack_frames_cache; if (cache != null) cache.dispose(); } } diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStepQueueManager.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStepQueueManager.java deleted file mode 100644 index dd5e2042b..000000000 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStepQueueManager.java +++ /dev/null @@ -1,233 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems, Inc. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.tm.internal.tcf.dsf.services; - -import java.util.HashMap; -import java.util.Hashtable; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.DMContexts; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.service.IStepQueueManager; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; -import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; -import org.eclipse.dd.dsf.debug.service.IRunControl.StepType; -import org.eclipse.dd.dsf.service.AbstractDsfService; -import org.eclipse.dd.dsf.service.DsfServiceEventHandler; -import org.eclipse.dd.dsf.service.DsfSession; -import org.eclipse.tm.internal.tcf.dsf.Activator; -import org.osgi.framework.BundleContext; - - -public class TCFDSFStepQueueManager extends AbstractDsfService -implements IStepQueueManager{ - - private static class StepRequest { - StepType fStepType; - boolean fIsInstructionStep; - StepRequest(StepType type, boolean instruction) { - fStepType = type; - fIsInstructionStep = instruction; - } - } - - private IRunControl fRunControl; - private int fQueueDepth = 3; - private Map<IExecutionDMContext,List<StepRequest>> fStepQueues = new HashMap<IExecutionDMContext,List<StepRequest>>(); - private Map<IExecutionDMContext,Boolean> fTimedOutFlags = new HashMap<IExecutionDMContext,Boolean>(); - private Map<IExecutionDMContext,ScheduledFuture<?>> fTimedOutFutures = new HashMap<IExecutionDMContext,ScheduledFuture<?>>(); - - public TCFDSFStepQueueManager(DsfSession session) { - super(session); - } - - /////////////////////////////////////////////////////////////////////////// - // IDsfService - @Override - public void initialize(final RequestMonitor requestMonitor) { - super.initialize( - new RequestMonitor(getExecutor(), requestMonitor) { - @Override - protected void handleOK() { - doInitialize(requestMonitor); - }}); - } - - private void doInitialize(final RequestMonitor requestMonitor) { - fRunControl = getServicesTracker().getService(IRunControl.class); - - getSession().addServiceEventListener(this, null); - register(new String[]{IStepQueueManager.class.getName()}, new Hashtable<String,String>()); - requestMonitor.done(); - } - - @Override - public void shutdown(final RequestMonitor requestMonitor) { - unregister(); - getSession().removeServiceEventListener(this); - super.shutdown(requestMonitor); - } - - /////////////////////////////////////////////////////////////////////////// - // AbstractService - @Override - protected BundleContext getBundleContext() { - return Activator.getBundleContext(); - } - - /////////////////////////////////////////////////////////////////////////// - // IStepQueueManager - public boolean canEnqueueStep(IDMContext ctx) { - IExecutionDMContext execCtx = DMContexts.getAncestorOfType(ctx, IExecutionDMContext.class); - return execCtx != null && - ( (fRunControl.isSuspended(execCtx) && fRunControl.canStep(execCtx)) || - (fRunControl.isStepping(execCtx) && !isSteppingTimedOut(execCtx)) ); - } - - // IStepQueueManager - public boolean canEnqueueInstructionStep(IDMContext ctx) { - IExecutionDMContext execCtx = DMContexts.getAncestorOfType(ctx, IExecutionDMContext.class); - return execCtx != null && - ( (fRunControl.isSuspended(execCtx) && fRunControl.canInstructionStep(execCtx)) || - (fRunControl.isStepping(execCtx) && !isSteppingTimedOut(execCtx)) ); - } - - public int getPendingStepCount(IDMContext execCtx) { - List<StepRequest> stepQueue = fStepQueues.get(execCtx); - if (stepQueue == null) return 0; - return stepQueue.size(); - } - - public void enqueueStep(IDMContext ctx, StepType stepType) { - IExecutionDMContext execCtx = DMContexts.getAncestorOfType(ctx, IExecutionDMContext.class); - if (execCtx != null) { - if (fRunControl.canStep(execCtx)) { - fRunControl.step(execCtx, stepType, new RequestMonitor(getExecutor(), null)); - } else if (canEnqueueStep(execCtx)) { - List<StepRequest> stepQueue = fStepQueues.get(execCtx); - if (stepQueue == null) { - stepQueue = new LinkedList<StepRequest>(); - fStepQueues.put(execCtx, stepQueue); - } - if (stepQueue.size() < fQueueDepth) { - stepQueue.add(new StepRequest(stepType, false)); - } - } - } - } - - public void enqueueInstructionStep(IDMContext ctx, StepType stepType) { - IExecutionDMContext execCtx = DMContexts.getAncestorOfType(ctx, IExecutionDMContext.class); - if (execCtx != null) { - if (fRunControl.canInstructionStep(execCtx)) { - fRunControl.instructionStep(execCtx, stepType, new RequestMonitor(getExecutor(), null)); - } - else if (canEnqueueInstructionStep(execCtx)) { - List<StepRequest> stepQueue = fStepQueues.get(execCtx); - if (stepQueue == null) { - stepQueue = new LinkedList<StepRequest>(); - fStepQueues.put(execCtx, stepQueue); - } - if (stepQueue.size() < fQueueDepth) { - stepQueue.add(new StepRequest(stepType, true)); - } - } - } - } - - public boolean isSteppingTimedOut(IDMContext context) { - IExecutionDMContext execCtx = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); - if (execCtx != null) { - return fTimedOutFlags.containsKey(execCtx) ? fTimedOutFlags.get(execCtx) : false; - } - return false; - } - - - public int getStepQueueDepth() { return fQueueDepth; } - public void setStepQueueDepth(int depth) { fQueueDepth = depth; } - - /////////////////////////////////////////////////////////////////////////// - - @DsfServiceEventHandler - public void eventDispatched(ISuspendedDMEvent e) { - // Take care of the stepping time out - fTimedOutFlags.remove(e.getDMContext()); - ScheduledFuture<?> future = fTimedOutFutures.remove(e.getDMContext()); - if (future != null) future.cancel(false); - - // Check if there's a step pending, if so execute it - if (fStepQueues.containsKey(e.getDMContext())) { - List<StepRequest> queue = fStepQueues.get(e.getDMContext()); - StepRequest request = queue.remove(queue.size() - 1); - if (queue.isEmpty()) fStepQueues.remove(e.getDMContext()); - if (request.fIsInstructionStep) { - if (fRunControl.canInstructionStep(e.getDMContext())) { - fRunControl.instructionStep( - e.getDMContext(), request.fStepType, new RequestMonitor(getExecutor(), null)); - } else { - // For whatever reason we can't step anymore, so clear out - // the step queue. - fStepQueues.remove(e.getDMContext()); - } - } else { - if (fRunControl.canStep(e.getDMContext())) { - fRunControl.step(e.getDMContext(), request.fStepType,new RequestMonitor(getExecutor(), null)); - } else { - // For whatever reason we can't step anymore, so clear out - // the step queue. - fStepQueues.remove(e.getDMContext()); - } - } - } - } - - @DsfServiceEventHandler - public void eventDispatched(final IResumedDMEvent e) { - if (e.getReason().equals(StateChangeReason.STEP)) { - fTimedOutFlags.put(e.getDMContext(), Boolean.FALSE); - // We shouldn't have a stepping timeout running unless we get two - // stepping events in a row without a suspended, which would be a - // protocol error. - assert !fTimedOutFutures.containsKey(e.getDMContext()); - fTimedOutFutures.put( - e.getDMContext(), - getExecutor().schedule( - new DsfRunnable() { public void run() { - fTimedOutFutures.remove(e.getDMContext()); - - // Issue the stepping time-out event. - getSession().dispatchEvent( - new ISteppingTimedOutEvent() { - public IExecutionDMContext getDMContext() { return e.getDMContext(); } - }, - getProperties()); - }}, - STEPPING_TIMEOUT, TimeUnit.MILLISECONDS) - ); - - } - } - - @DsfServiceEventHandler - public void eventDispatched(ISteppingTimedOutEvent e) { - fTimedOutFlags.put(e.getDMContext(), Boolean.TRUE); - } -} diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFThreadDMC.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFThreadDMC.java deleted file mode 100644 index eaf308a9b..000000000 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFThreadDMC.java +++ /dev/null @@ -1,23 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.tm.internal.tcf.dsf.services; - -import org.eclipse.dd.dsf.datamodel.AbstractDMContext; -import org.eclipse.dd.dsf.datamodel.IDMContext; -import org.eclipse.dd.dsf.debug.service.INativeProcesses.IThreadDMContext; -import org.eclipse.dd.dsf.service.IDsfService; - -public abstract class TCFDSFThreadDMC extends AbstractDMContext implements IThreadDMContext { - - public TCFDSFThreadDMC(IDsfService service, IDMContext[] parents) { - super(service, parents); - } -} diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDataCache.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDataCache.java deleted file mode 100644 index e95bb43d4..000000000 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDataCache.java +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems, Inc. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.tm.internal.tcf.dsf.services; - -import java.util.ArrayList; -import java.util.Collection; - -import org.eclipse.tm.tcf.protocol.IChannel; -import org.eclipse.tm.tcf.protocol.IToken; -import org.eclipse.tm.tcf.protocol.Protocol; - - -public abstract class TCFDataCache<V> { - - protected Throwable error; - protected IToken command; - protected boolean valid; - protected V data; - - protected final IChannel channel; - protected final Collection<IDataRequest> waiting_list = new ArrayList<IDataRequest>(); - - public TCFDataCache(IChannel channel) { - assert channel != null; - this.channel = channel; - } - - public void cancel() { - // Cancel current data retrieval command - if (command != null) { - command.cancel(); - command = null; - } - // Cancel waiting data requests - if (!waiting_list.isEmpty()) { - IDataRequest[] arr = waiting_list.toArray(new IDataRequest[waiting_list.size()]); - waiting_list.clear(); - for (IDataRequest r : arr) r.cancel(); - } - } - - public boolean validate() { - assert Protocol.isDispatchThread(); - if (channel.getState() != IChannel.STATE_OPEN) { - error = null; - command = null; - data = null; - valid = true; - return true; - } - if (command != null) { - return false; - } - if (!valid && !startDataRetrieval()) return false; - assert command == null; - if (!waiting_list.isEmpty()) { - IDataRequest[] arr = waiting_list.toArray(new IDataRequest[waiting_list.size()]); - waiting_list.clear(); - for (IDataRequest r : arr) r.done(); - } - return true; - } - - public void addWaitingRequest(IDataRequest req) { - assert !valid; - waiting_list.add(req); - } - - public void reset(V data) { - cancel(); - this.data = data; - error = null; - valid = true; - } - - public void reset() { - cancel(); - error = null; - data = null; - valid = false; - } - - public boolean isValid() { - return valid; - } - - public Throwable getError() { - assert valid; - return error; - } - - public V getData() { - assert valid; - return data; - } - - public abstract boolean startDataRetrieval(); -} diff --git a/plugins/org.eclipse.tm.tcf.rse/src/org/eclipse/tm/internal/tcf/rse/processes/TCFSystemViewRemoteProcessAdapter.java b/plugins/org.eclipse.tm.tcf.rse/src/org/eclipse/tm/internal/tcf/rse/processes/TCFSystemViewRemoteProcessAdapter.java index 6bdc66bcb..8a66fce85 100644 --- a/plugins/org.eclipse.tm.tcf.rse/src/org/eclipse/tm/internal/tcf/rse/processes/TCFSystemViewRemoteProcessAdapter.java +++ b/plugins/org.eclipse.tm.tcf.rse/src/org/eclipse/tm/internal/tcf/rse/processes/TCFSystemViewRemoteProcessAdapter.java @@ -261,7 +261,7 @@ public class TCFSystemViewRemoteProcessAdapter extends AbstractSystemViewAdapter if (formatted) { if (name.equals(ISysMonitor.PROP_VSIZE)) { - return NLS.bind(Messages.PROCESS_VMSIZE_VALUE, Long + return NLS.bind(Messages.PROCESS_VMSIZE_VALUE, Long .toString(process.getVmSizeInKB())); } if (name.equals(ISysMonitor.PROP_RSS)) { diff --git a/plugins/org.eclipse.tm.tcf/build.properties b/plugins/org.eclipse.tm.tcf/build.properties index cdd2db7f1..f70828ba5 100644 --- a/plugins/org.eclipse.tm.tcf/build.properties +++ b/plugins/org.eclipse.tm.tcf/build.properties @@ -3,5 +3,6 @@ output.. = bin/ bin.includes = META-INF/,\ .,\ about.html,\ - plugin.properties + plugin.properties,\ + plugin.xml src.includes = about.html diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ProcessesProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ProcessesProxy.java index 7c25cf51d..829e41d83 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ProcessesProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ProcessesProxy.java @@ -130,7 +130,6 @@ public class ProcessesProxy implements IProcesses { public IToken getChildren(String parent_context_id, boolean attached_only, final DoneGetChildren done) { return new Command(channel, this, "getChildren", new Object[]{ parent_context_id, attached_only }) { - @SuppressWarnings("unchecked") @Override public void done(Exception error, Object[] args) { String[] ids = null; @@ -165,7 +164,6 @@ public class ProcessesProxy implements IProcesses { public IToken getEnvironment(final DoneGetEnvironment done) { return new Command(channel, this, "getEnvironment", null) { - @SuppressWarnings("unchecked") @Override public void done(Exception error, Object[] args) { Map<String,String> env = null; diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RegistersProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RegistersProxy.java index 5c64aae33..127d58bc4 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RegistersProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RegistersProxy.java @@ -210,7 +210,6 @@ public class RegistersProxy implements IRegisters { public IToken getm(Location[] locs, final DoneGet done) { return new Command(channel, this, "getm", new Object[]{ locs }) { - @SuppressWarnings("unchecked") @Override public void done(Exception error, Object[] args) { byte[] val = null; diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RunControlProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RunControlProxy.java index cf42aad41..10bd33699 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RunControlProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/RunControlProxy.java @@ -230,7 +230,6 @@ public class RunControlProxy implements IRunControl { public IToken getChildren(String parent_context_id, final DoneGetChildren done) { return new Command(channel, this, "getChildren", new Object[]{ parent_context_id }) { - @SuppressWarnings("unchecked") @Override public void done(Exception error, Object[] args) { String[] arr = null; diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/StackTraceProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/StackTraceProxy.java index 074f1d25e..e59aa731f 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/StackTraceProxy.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/StackTraceProxy.java @@ -89,7 +89,6 @@ public class StackTraceProxy implements IStackTrace { public IToken getContext(String[] id, final DoneGetContext done) { return new Command(channel, this, "getContext", new Object[]{ id }) { - @SuppressWarnings("unchecked") @Override public void done(Exception error, Object[] args) { StackTraceContext[] arr = null; diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/EventQueue.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/EventQueue.java index 7c05085f0..61bb453cd 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/EventQueue.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/EventQueue.java @@ -43,7 +43,6 @@ class EventQueue implements IEventQueue, Runnable { } public void awake(IJobChangeEvent event) { - //job_cnt++; } public void done(IJobChangeEvent event) { @@ -58,7 +57,6 @@ class EventQueue implements IEventQueue, Runnable { } public void sleeping(IJobChangeEvent event) { - //job_cnt--; } }); } @@ -92,6 +90,7 @@ class EventQueue implements IEventQueue, Runnable { } public synchronized void invokeLater(final Runnable r) { + assert r != null; queue.add(r); if (waiting) { waiting = false; @@ -104,8 +103,8 @@ class EventQueue implements IEventQueue, Runnable { } public synchronized int getCongestion() { - int l0 = job_cnt / 100 - 100; - int l1 = queue.size() / 100 - 100; + int l0 = job_cnt / 10 - 100; + int l1 = queue.size() / 10 - 100; if (l1 > l0) l0 = l1; if (l0 > 100) l0 = 100; return l0; diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java index 0dcd50ac9..1b5cf3edc 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractChannel.java @@ -11,6 +11,9 @@ package org.eclipse.tm.tcf.core; import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryMXBean; +import java.lang.management.MemoryUsage; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -120,12 +123,15 @@ public abstract class AbstractChannel implements IChannel { private IToken redirect_command; private IPeer peer; - private static final int pending_command_limit = 10; + private static final int pending_command_limit = 32; private int local_congestion_level = -100; private int remote_congestion_level = -100; private long local_congestion_time; - private int inp_queue_size = 0; + private int local_congestion_cnt; private Collection<TraceListener> trace_listeners; + + private static final MemoryMXBean mem_mbean = ManagementFactory.getMemoryMXBean(); + private static final long mem_limit = 32000000; public static final int EOS = -1, // End Of Stream @@ -203,16 +209,12 @@ public abstract class AbstractChannel implements IChannel { default: error(); } - long delay = 0; - synchronized (out_queue) { - inp_queue_size++; - if (inp_queue_size > 32) delay = inp_queue_size; - } Protocol.invokeLater(new Runnable() { public void run() { handleInput(msg); } }); + int delay = local_congestion_level; if (delay > 0) sleep(delay); } Protocol.invokeLater(new Runnable() { @@ -366,7 +368,6 @@ public abstract class AbstractChannel implements IChannel { } } - @SuppressWarnings("unchecked") private void onLocatorHello(Collection<String> c) throws IOException { if (state != STATE_OPENNING) throw new IOException("Invalid event: Locator.Hello"); remote_service_by_class.clear(); @@ -667,9 +668,6 @@ public abstract class AbstractChannel implements IChannel { @SuppressWarnings("unchecked") private void handleInput(Message msg) { assert Protocol.isDispatchThread(); - synchronized (out_queue) { - inp_queue_size--; - } if (state == STATE_CLOSED) return; if (trace_listeners != null) { for (TraceListener l : trace_listeners) { @@ -698,15 +696,16 @@ public abstract class AbstractChannel implements IChannel { else { throw new IOException("Unknown command " + msg.service + "." + msg.name); } - sendCongestionLevel(); break; case 'P': token = out_tokens.get(msg.token.getID()).token; token.getListener().progress(token, msg.data); + sendCongestionLevel(); break; case 'R': token = out_tokens.remove(msg.token.getID()).token; token.getListener().result(token, msg.data); + sendCongestionLevel(); break; case 'E': if (msg.service.equals(ILocator.NAME) && msg.name.equals("Hello")) { @@ -723,7 +722,7 @@ public abstract class AbstractChannel implements IChannel { } break; case 'F': - remote_congestion_level = Integer.parseInt(new String(msg.data, "UTF8")); + remote_congestion_level = Integer.parseInt(new String(msg.data, "ASCII")); break; default: assert false; @@ -736,23 +735,26 @@ public abstract class AbstractChannel implements IChannel { } private void sendCongestionLevel() throws IOException { - assert Protocol.isDispatchThread(); + if (++local_congestion_cnt < 8) return; + local_congestion_cnt = 0; if (state != STATE_OPEN) return; - int level = Protocol.getEventQueue().getCongestion(); + long time = System.currentTimeMillis(); + if (time - local_congestion_time < 500) return; + assert Protocol.isDispatchThread(); + int level = Protocol.getCongestionLevel(); int n = inp_tokens.size() * 100 / pending_command_limit - 100; if (n > level) level = n; + MemoryUsage mem_usage = mem_mbean.getHeapMemoryUsage(); + long mem_free = mem_usage.getMax() - mem_usage.getUsed(); + n = (int)((mem_limit - mem_free) * 100 / mem_limit); + if (n > 0) mem_mbean.gc(); + if (n > level) level = n; + n = Protocol.getCongestionLevel(); + if (n > level) level = n; if (level > 100) level = 100; if (level == local_congestion_level) return; - long time = System.currentTimeMillis(); - if (level < local_congestion_level) { - if (time - local_congestion_time < 500) return; - int i = (local_congestion_level - level) / 4; - if (i <= 0) i = 1; - local_congestion_level -= i; - } - else { - local_congestion_level = level; - } + int i = (level - local_congestion_level) / 8; + if (i != 0) level = local_congestion_level + i; local_congestion_time = time; synchronized (out_queue) { Message msg = out_queue.isEmpty() ? null : out_queue.get(0); @@ -761,8 +763,9 @@ public abstract class AbstractChannel implements IChannel { out_queue.add(0, msg); out_queue.notify(); } - msg.data = Integer.toString(local_congestion_level).getBytes("UTF8"); + msg.data = Integer.toString(local_congestion_level).getBytes("ASCII"); msg.trace = trace_listeners; + local_congestion_level = level; } } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/IChannel.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/IChannel.java index 3a8b4e52c..f6e2b3481 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/IChannel.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/IChannel.java @@ -88,14 +88,16 @@ public interface IChannel { void sendResult(IToken token, byte[] results); /** - * Get current level of outbound traffic congestion. + * Get current level of out-bound traffic congestion. * * @return integer value in range –100..100, where –100 means no pending * messages (no traffic), 0 means optimal load, and positive numbers * indicate level of congestion. * - * Note: inbound traffic congestion is detected by framework and reported to - * remote peer without client needed to be involved. + * Note: in-bound traffic congestion is detected by framework and reported to + * remote peer without client needed to be involved. Clients willing to provide + * additional data about local congestion should register itself using + * Protocol.addCongestionMonitor(). */ int getCongestion(); @@ -118,7 +120,7 @@ public interface IChannel { void onChannelClosed(Throwable error); /** - * Notifies listeners about channel congestion level changes. + * Notifies listeners about channel out-bound traffic congestion level changes. * When level > 0 client should delay sending more messages. * @param level - current congestion level */ @@ -127,7 +129,7 @@ public interface IChannel { /** * Subscribe a channel listener. The listener will be notified about changes of - * channel state and changes of outbound traffic congestion level. + * channel state and changes of out-bound traffic congestion level. * @param listener - channel listener implementation */ void addChannelListener(IChannelListener listener); diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/Protocol.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/Protocol.java index 4c41d6b3d..9d8b7feeb 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/Protocol.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/protocol/Protocol.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.tm.tcf.protocol; +import java.util.ArrayList; + import org.eclipse.tm.internal.tcf.core.LocalPeer; import org.eclipse.tm.internal.tcf.core.Transport; import org.eclipse.tm.internal.tcf.services.local.LocatorService; @@ -17,7 +19,6 @@ import org.eclipse.tm.tcf.services.ILocator; /** - * * Class Protocol provides static methods to access Target Communication Framework root objects: * 1. the framework event queue and dispatch thread; * 2. local instance of Locator service, which maintains a list of available targets; @@ -26,6 +27,8 @@ import org.eclipse.tm.tcf.services.ILocator; public class Protocol { private static IEventQueue event_queue; + + private static final ArrayList<CongestionMonitor> congestion_monitors = new ArrayList<CongestionMonitor>(); /** * Before TCF can be used it should be given an object implementing IEventQueue interface. @@ -92,6 +95,8 @@ public class Protocol { * Causes <code>runnable</code> to have its <code>run</code> * method called in the dispatch thread of the framework. * Calling thread is suspended until the method is executed. + * If invokeAndWait is called from the dispatching thread + * the <i>runnable.run()</i> is executed immediately. * * This method can be invoked from any thread. * @@ -191,4 +196,64 @@ public class Protocol { public static void sync(Runnable done) { Transport.sync(done); } + + /** + * Clients implement CongestionMonitor interface to monitor usage of local resources, + * like, for example, display queue size - if the queue becomes too big, UI response time + * can become too high, or it can crash all together because of OutOfMemory errors. + * TCF flow control logic prevents such conditions by throttling traffic coming from remote peers. + * Note: Local (in-bound traffic) congestion is detected by framework and reported to + * remote peer without client needed to be involved. Only clients willing to provide + * additional data about local congestion should implement CongestionMonitor and + * register it using Protocol.addCongestionMonitor(). + */ + public interface CongestionMonitor { + /** + * Get current level of client resource utilization. + * @return integer value in range –100..100, where –100 means all resources are free, + * 0 means optimal load, and positive numbers indicate level of congestion. + */ + int getCongestionLevel(); + } + + /** + * Register a congestion monitor. + * @param monitor - client implementation of CongestionMonitor interface + */ + public static void addCongestionMonitor(CongestionMonitor monitor) { + assert monitor != null; + assert isDispatchThread(); + congestion_monitors.add(monitor); + } + + /** + * Unregister a congestion monitor. + * @param monitor - client implementation of CongestionMonitor interface + */ + public static void removeCongestionMonitor(CongestionMonitor monitor) { + assert isDispatchThread(); + congestion_monitors.remove(monitor); + } + + /** + * Get current level of local traffic congestion. + * + * @return integer value in range –100..100, where –100 means no pending + * messages (no traffic), 0 means optimal load, and positive numbers + * indicate level of congestion. + */ + public static int getCongestionLevel() { + assert isDispatchThread(); + int level = -100; + for (CongestionMonitor m : congestion_monitors) { + int n = m.getCongestionLevel(); + if (n > level) level = n; + } + if (event_queue != null) { + int n = event_queue.getCongestion(); + if (n > level) level = n; + } + if (level > 100) level = 100; + return level; + } } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IBreakpoints.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IBreakpoints.java index c29e100e3..6d3b204b6 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IBreakpoints.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IBreakpoints.java @@ -46,13 +46,14 @@ public interface IBreakpoints extends IService { PROP_CONDITION = "Condition", // String PROP_FILE = "File", // String PROP_LINE = "Line", // Number - PROP_COLUMN = "Column"; // Number + PROP_COLUMN = "Column", // Number + PROP_SKIP_COUNT = "SkipCount"; // Number /** * Breakpoint status field names. */ static final String - STATUS_PLANTED = "Planted", // Array of addresses + STATUS_PLANTED = "Planted", // Map<String: Memory context ID,Collection<Number: address>> STATUS_ERROR = "Error", // String STATUS_FILE = "File", // String STATUS_LINE = "Line", // Number diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IFileSystem.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IFileSystem.java index b7af9a306..fb2a8b26f 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IFileSystem.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IFileSystem.java @@ -353,6 +353,7 @@ public interface IFileSystem extends IService { */ STATUS_OP_UNSUPPORTED = 8; + @SuppressWarnings("serial") abstract static class FileSystemException extends IOException { protected FileSystemException(String message) { diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDataCache.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/util/TCFDataCache.java index 5584a02ed..15246d90e 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDataCache.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/util/TCFDataCache.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.tm.internal.tcf.debug.ui.model; +package org.eclipse.tm.tcf.util; import java.util.HashSet; @@ -41,7 +41,7 @@ public abstract class TCFDataCache<V> implements Runnable { } /** - * @return true if cache contains up-to-date data (or data error). + * @return true if cache contains up-to-date data (or data retrieval error). */ public boolean isValid() { return valid; @@ -73,8 +73,8 @@ public abstract class TCFDataCache<V> implements Runnable { } /** - * Notify waiting clients about cache state change and remove then from wait list. - * It is responsibility of clients to check if state change was one they are waiting for. + * Notify waiting clients about cache state change and remove them from wait list. + * It is responsibility of clients to check if the state change was one they are waiting for. */ public void run() { if (waiting_list.isEmpty()) return; @@ -94,7 +94,7 @@ public abstract class TCFDataCache<V> implements Runnable { /** * Initiate data retrieval if the cache is not valid. - * @return + * @return true if the cache is already valid */ public boolean validate() { assert Protocol.isDispatchThread(); |