From a9183acf706be3c4a0f41a5572382acf9d0f0e28 Mon Sep 17 00:00:00 2001 From: eutarass Date: Sat, 3 May 2008 00:44:46 +0000 Subject: 1. Bug 225555: [tcf] Migrate to DSF 1.0M6 2. Since DSF 1.0 requires it, migrated to Eclipse 3.4M6 and CDT 5.0M6 3. Since DSF is not fast enough to keep up with rapid target state changes when TCF diagnostic is running, reworked TCF flow control logic and added TCF API for client congestion monitoring, which is used to monitor DSF UI event queue. --- .../tm/internal/tcf/dsf/launch/TCFDSFLaunch.java | 16 +- .../tcf/dsf/launch/TCFDSFLaunchSequence.java | 13 +- .../tcf/dsf/launch/TCFDSFShutdownSequence.java | 117 ++++ .../tm/internal/tcf/dsf/services/IDataRequest.java | 17 - .../tm/internal/tcf/dsf/services/TCFAddress.java | 1 + .../tcf/dsf/services/TCFDSFBreakpoints.java | 286 ++++++---- .../tcf/dsf/services/TCFDSFExecutionDMC.java | 139 ++++- .../tm/internal/tcf/dsf/services/TCFDSFMemory.java | 122 ++-- .../tcf/dsf/services/TCFDSFNativeProcesses.java | 614 --------------------- .../tcf/dsf/services/TCFDSFProcessDMC.java | 23 - .../internal/tcf/dsf/services/TCFDSFRegisters.java | 436 +++++++++------ .../tcf/dsf/services/TCFDSFRunControl.java | 603 +++++++------------- .../tcf/dsf/services/TCFDSFRunControlState.java | 19 + .../tm/internal/tcf/dsf/services/TCFDSFStack.java | 260 ++++----- .../tcf/dsf/services/TCFDSFStepQueueManager.java | 233 -------- .../internal/tcf/dsf/services/TCFDSFThreadDMC.java | 23 - .../tm/internal/tcf/dsf/services/TCFDataCache.java | 106 ---- 17 files changed, 1091 insertions(+), 1937 deletions(-) create mode 100644 plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFShutdownSequence.java delete mode 100644 plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/IDataRequest.java delete mode 100644 plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFNativeProcesses.java delete mode 100644 plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFProcessDMC.java create mode 100644 plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRunControlState.java delete mode 100644 plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStepQueueManager.java delete mode 100644 plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFThreadDMC.java delete mode 100644 plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDataCache.java (limited to 'plugins/org.eclipse.tm.tcf.dsf') 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> status; + final Set 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 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(); } @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 attrs; + final Map status; + final String file; - BreakpointData(IBreakpoint bp, BreakpointStatus status) { + @SuppressWarnings("unchecked") + BreakpointData(IBreakpoint bp, Map 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 getStatus() { return status; } + + @SuppressWarnings("unchecked") + public IAddress[] getAddresses() { + if (status == null) return null; + Map> arr = (Map>)status.get(IBreakpoints.STATUS_PLANTED); + if (arr == null) return null; + int cnt = 0; + for (Collection c : arr.values()) cnt += c.size(); + IAddress[] res = new IAddress[cnt]; + int pos = 0; + for (Collection 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 map = launch.getBreakpointsStatus().getStatus(dmc.id); + TCFDSFRunControl rc = getServicesTracker().getService(TCFDSFRunControl.class); + Map 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 add_targets = new HashSet(); + Set rem_targets = new HashSet(); + if (map != null) { + Map> arr = (Map>)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 cache = new HashMap(); + 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 rm) { - IBreakpointManager bp_manager = DebugPlugin.getDefault().getBreakpointManager(); + public void getBreakpoints(IBreakpointsTargetDMContext ctx, DataRequestMonitor rm) { TCFBreakpointsModel m = TCFBreakpointsModel.getBreakpointsModel(); IBreakpoint[] arr = bp_manager.getBreakpoints(ITCFConstants.ID_TCF_DEBUG_MODEL); ArrayList l = new ArrayList(); @@ -233,36 +325,13 @@ public class TCFDSFBreakpoints extends AbstractDsfService implements org.eclipse rm.done(); } - public void getBreakpoints(IDMContext dmc, IBreakpoint bp, DataRequestMonitor rm) { - TCFBreakpointsModel m = TCFBreakpointsModel.getBreakpointsModel(); - ArrayList l = new ArrayList(); - 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 rm) { + public void getBreakpointDMData(final IBreakpointDMContext dmc, final DataRequestMonitor 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 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)rm); + getBreakpointDMData((BreakpointDMC)dmc, (DataRequestMonitor)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 attributes, + DataRequestMonitor 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 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 memory_context_cache; + public final TCFDataCache run_control_context_cache; + public final TCFDataCache> run_control_children_cache; + public final TCFDataCache 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(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(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>(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 data = new HashMap(); + 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(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 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 implements IMemoryChangedEvent { + IAddress[] fAddresses; + IDMContext fContext; - final TCFDataCache context; - - MemoryCache(final IChannel channel, final TCFDSFExecutionDMC exe) { - context = new TCFDataCache(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 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 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 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 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 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 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 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 params) { - } - }; - - private final IProcesses tcf_prs_service; - private final org.eclipse.tm.tcf.services.IRunControl tcf_run_service; - private final Map process_cache = new HashMap(); // all attached processes - private final Map thread_cache = new HashMap(); // 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()); - monitor.done(); - } - }); - } - - @Override - public void initialize(final RequestMonitor monitor) { - final Collection list = new ArrayList(); - final Set cmds = new HashSet(); - 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 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 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 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 rm) { - rm.setData(process_cache.values().toArray(new IProcessDMContext[process_cache.size()])); - rm.done(); - } - - public void getRunningProcesses(final DataRequestMonitor rm) { - final Collection list = new ArrayList(); - final Set cmds = new HashSet(); - 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)rm); - } - else if (dmc instanceof ThreadDMC) { - getThreadData((ThreadDMC)dmc, (DataRequestMonitor)rm); - } - else if (dmc == service_dmc) { - ((DataRequestMonitor)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 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 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 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(); 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> - implements TCFDSFExecutionDMC.DataCache { + private class RegisterChildrenCache extends TCFDataCache> { final String id; final IDMContext[] parents; + Map dmc_pool = new HashMap();; 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 data = new LinkedHashMap(); + if (err != null || contexts == null || contexts.length == 0) { + set(token, err, data); + return; } - else { - data = new LinkedHashMap(); - if (contexts.length > 0) { - // TODO DSF service design does not support lazy retrieval of context attributes (because getName() is not async) - final Set cmds = new HashSet(); - 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 cmds = new HashSet(); + 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 - implements IGroupsChangedDMEvent { + private static class GroupsChangedEvent extends AbstractDMEvent 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 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 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 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 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 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 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 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 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 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 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 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 implements IContainerResumedDMEvent { + public class ContainerResumedEvent extends AbstractDMEvent 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 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 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 implements IExitedDMEvent { - - private final IExecutionDMContext exe; + public static class ExitedEvent extends AbstractDMEvent 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 suspend_params; - } - private class ExecutionDMC extends TCFDSFExecutionDMC { final String id; @@ -231,124 +218,31 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. int is_stepping; int is_resuming; - final TCFDataCache context; - final TCFDataCache> children; - final TCFDataCache 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(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>(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(); - 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(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 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$ @@ -383,38 +277,21 @@ public class TCFDSFRunControl extends AbstractDsfService implements org.eclipse. return id; } - @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 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 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 m = children.getData(); + n.run_control_context_cache.reset(c); + if (run_control_children_cache.isValid()) { + Map 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 m = parent.children.getData(); + if (parent != null && parent.run_control_children_cache.isValid()) { + Map 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 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 cache = new HashMap(); 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)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)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)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)rm).setData(dt); rm.done(); } - else if (dmc == service_dmc) { - ((DataRequestMonitor)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 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 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 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 rm) { - getContexts(context, rm, false); + getContexts(context, rm, false, false); } public void getExecutionContexts(IContainerDMContext context, final DataRequestMonitor rm) { - getContexts(context, rm, true); + getContexts(context, rm, false, true); + } + + public void getAllContexts(IContainerDMContext context, final DataRequestMonitor rm) { + getContexts(context, rm, true, true); } public void getContexts(IContainerDMContext context, - final DataRequestMonitor rm, final boolean has_state) { + final DataRequestMonitor rm, + final boolean all, final boolean has_state) { if (context == null) context = root_dmc; if (context instanceof ExecutionDMC) { final ExecutionDMC ctx = (ExecutionDMC)context; - TCFDataCache> cache = ctx.children; + TCFDataCache> 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 reqs = new HashSet(); - 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 reqs = new HashSet(); + 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 l = new ArrayList(); - for (ExecutionDMC e : cache.getData().values()) { - assert e.context.isValid(); - RunControlContext c = e.context.getData(); - if (c.hasState() == has_state) l.add(e); + ArrayList l = new ArrayList(); + 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 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 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 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 { + class TCFFrameDMC extends AbstractDMContext implements IFrameDMContext, Comparable { 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 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> implements TCFDSFExecutionDMC.DataCache { + private class FramesCache extends TCFDataCache> { private final TCFDSFExecutionDMC dmc; private final Map 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(); + HashMap data = new HashMap(); + 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 rm) { + public void getArguments(IFrameDMContext dmc, DataRequestMonitor 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 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 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 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 c = cache.getData(); - TCFFrameDMC[] arr = c.values().toArray(new TCFFrameDMC[c.size()]); + Map 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 rm) { + public void getLocals(IFrameDMContext dmc, DataRequestMonitor 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 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 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 rm) { + public void getStackDepth(final IDMContext dmc, final int maxDepth, final DataRequestMonitor 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 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)rm); } - else if (dmc == service_dmc) { - ((DataRequestMonitor)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> fStepQueues = new HashMap>(); - private Map fTimedOutFlags = new HashMap(); - private Map> fTimedOutFutures = new HashMap>(); - - 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()); - 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 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 stepQueue = fStepQueues.get(execCtx); - if (stepQueue == null) { - stepQueue = new LinkedList(); - 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 stepQueue = fStepQueues.get(execCtx); - if (stepQueue == null) { - stepQueue = new LinkedList(); - 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 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 { - - protected Throwable error; - protected IToken command; - protected boolean valid; - protected V data; - - protected final IChannel channel; - protected final Collection waiting_list = new ArrayList(); - - 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(); -} -- cgit v1.2.3