diff options
author | Eugene Tarassov | 2011-11-28 16:35:06 +0000 |
---|---|---|
committer | Eugene Tarassov | 2011-11-28 16:35:06 +0000 |
commit | bec08e6e0af73f33c0fc57ac7b441a39e1c20672 (patch) | |
tree | c11d36d847abd2e175b60d4ea3867d2d0b470fdd /plugins | |
parent | 32ef6d7f15016a690e8c0dea6bef284c90abbd9b (diff) | |
download | org.eclipse.tcf-bec08e6e0af73f33c0fc57ac7b441a39e1c20672.tar.gz org.eclipse.tcf-bec08e6e0af73f33c0fc57ac7b441a39e1c20672.tar.xz org.eclipse.tcf-bec08e6e0af73f33c0fc57ac7b441a39e1c20672.zip |
TCF Debugger: added "Detach Debug Context" command in the Debug view.
Diffstat (limited to 'plugins')
8 files changed, 167 insertions, 11 deletions
diff --git a/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/internal/services/remote/RunControlProxy.java b/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/internal/services/remote/RunControlProxy.java index 4cefc7f43..0526c7736 100644 --- a/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/internal/services/remote/RunControlProxy.java +++ b/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/internal/services/remote/RunControlProxy.java @@ -98,6 +98,11 @@ public class RunControlProxy implements IRunControl { return b != null && b.booleanValue(); } + public boolean canDetach() { + Boolean b = (Boolean)props.get(PROP_CAN_DETACH); + return b != null && b.booleanValue(); + } + public String getRCGroup() { return (String)props.get(PROP_RC_GROUP); } @@ -149,6 +154,10 @@ public class RunControlProxy implements IRunControl { return command("terminate", new Object[]{ getID() }, done); } + public IToken detach(DoneCommand done) { + return command("detach", new Object[]{ getID() }, done); + } + private IToken command(String cmd, Object[] args, final DoneCommand done) { return new Command(channel, RunControlProxy.this, cmd, args) { @Override diff --git a/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/services/IRunControl.java b/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/services/IRunControl.java index 0eac356ea..0c17e0f5c 100644 --- a/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/services/IRunControl.java +++ b/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/services/IRunControl.java @@ -57,6 +57,9 @@ public interface IRunControl extends IService { /** true if terminate command is supported by the context */ PROP_CAN_TERMINATE = "CanTerminate", + /** true if detach command is supported by the context */ + PROP_CAN_DETACH = "CanDetach", + /** Context ID of a run control group that contains the context. * Members of same group are always suspended and resumed together: * resuming/suspending a context resumes/suspends all members of the group */ @@ -359,13 +362,23 @@ public interface IRunControl extends IService { * Utility method to read context property PROP_CAN_TERMINATE. * Value 'true' means terminate command is supported by the context, * however the method does not check that the command can be executed successfully in - * the current state of the context. For example, the command still can fail if context is - * already exited. - * @return value of PROP_CAN_SUSPEND. + * the current state of the context. For example, the command still can fail if the context + * already has exited. + * @return value of PROP_CAN_TERMINATE. */ boolean canTerminate(); /** + * Utility method to read context property PROP_CAN_DETACH. + * Value 'true' means detach command is supported by the context, + * however the method does not check that the command can be executed successfully in + * the current state of the context. For example, the command still can fail if the context + * already has exited. + * @return value of PROP_CAN_DETACH. + */ + boolean canDetach(); + + /** * Utility method to read context property PROP_RC_GROUP - * context ID of a run control group that contains the context. * Members of same group are always suspended and resumed together: @@ -435,6 +448,13 @@ public interface IRunControl extends IService { * @return pending command handle, can be used to cancel the command. */ IToken terminate(DoneCommand done); + + /** + * Send a command to detach a context. + * @param done - command result call back object. + * @return pending command handle, can be used to cancel the command. + */ + IToken detach(DoneCommand done); } class RunControlError extends Exception { diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/detach.gif b/plugins/org.eclipse.tcf.debug.ui/icons/detach.gif Binary files differnew file mode 100644 index 000000000..2f875e2da --- /dev/null +++ b/plugins/org.eclipse.tcf.debug.ui/icons/detach.gif diff --git a/plugins/org.eclipse.tcf.debug.ui/plugin.properties b/plugins/org.eclipse.tcf.debug.ui/plugin.properties index ad653cc8b..20877c8ce 100644 --- a/plugins/org.eclipse.tcf.debug.ui/plugin.properties +++ b/plugins/org.eclipse.tcf.debug.ui/plugin.properties @@ -28,6 +28,7 @@ ViewMemory.label = View Memory WatchInExpressions.label = Watch In Expressions Refresh.label = Refresh Console.label = Open Debug Console +Detach.label = Detach Debug Context UpdatePolicy.label = Update Policy CastToType.label=Cast To Type... diff --git a/plugins/org.eclipse.tcf.debug.ui/plugin.xml b/plugins/org.eclipse.tcf.debug.ui/plugin.xml index 4c9ccd3da..7b9fefe61 100644 --- a/plugins/org.eclipse.tcf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.tcf.debug.ui/plugin.xml @@ -295,6 +295,19 @@ </pluginState> </enablement> </action> + <action + id="org.eclipse.tcf.debug.ui.actions.Detach" + class="org.eclipse.tcf.internal.debug.ui.commands.DetachCommand" + icon="icons/detach.gif" + label="%Detach.label" + menubarPath="additions"> + <enablement> + <pluginState + value="activated" + id="org.eclipse.tcf.debug.ui"> + </pluginState> + </enablement> + </action> </objectContribution> <!-- TCFNodeExpression popup menu contributions --> diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/DetachCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/DetachCommand.java new file mode 100644 index 000000000..a6b055907 --- /dev/null +++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/DetachCommand.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2011 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.tcf.internal.debug.ui.commands; + +import org.eclipse.tcf.internal.debug.ui.model.TCFNode; +import org.eclipse.tcf.internal.debug.ui.model.TCFNodeExecContext; +import org.eclipse.tcf.protocol.IToken; +import org.eclipse.tcf.services.IRunControl; +import org.eclipse.tcf.util.TCFDataCache; +import org.eclipse.tcf.util.TCFTask; + +public class DetachCommand extends AbstractActionDelegate { + + private static boolean run(TCFNode[] nodes, final boolean dry_run) { + if (nodes == null || nodes.length == 0) return false; + for (TCFNode n : nodes) { + boolean ok = false; + while (!ok && n != null) { + if (n instanceof TCFNodeExecContext) { + final TCFNodeExecContext exe = (TCFNodeExecContext)n; + ok = new TCFTask<Boolean>(n.getChannel()) { + public void run() { + TCFDataCache<IRunControl.RunControlContext> ctx_cache = exe.getRunContext(); + if (!ctx_cache.validate(this)) return; + IRunControl.RunControlContext ctx_data = ctx_cache.getData(); + if (ctx_data != null && ctx_data.canDetach()) { + if (dry_run) { + done(true); + } + else { + ctx_data.detach(new IRunControl.DoneCommand() { + public void doneCommand(IToken token, Exception error) { + if (error != null) { + error(error); + } + else { + exe.getModel().getLaunch().onDetach(exe.getID()); + done(true); + } + } + }); + } + } + else { + done(false); + } + } + }.getE(); + } + n = n.getParent(); + } + if (!ok) return false; + } + return true; + } + + @Override + protected void selectionChanged() { + getAction().setEnabled(run(getSelectedNodes(), true)); + } + + @Override + protected void run() { + TCFNode[] nodes = getSelectedNodes(); + if (!run(nodes, true)) return; + run(nodes, false); + } +} diff --git a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java index 7776c5be2..53626dce2 100644 --- a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java +++ b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java @@ -1009,6 +1009,26 @@ public class TCFLaunch extends Launch { return connecting; } + public void onDetach(String prs_id) { + if (disconnecting) return; + if (process == null) return; + if (process_exited) return; + if (!prs_id.equals(process.getID())) return; + IProcesses processes = getService(IProcesses.class); + processes.removeListener(prs_listener); + IStreams streams = getService(IStreams.class); + for (String id : stream_ids.keySet()) { + streams.disconnect(id, new IStreams.DoneDisconnect() { + public void doneDisconnect(IToken token, Exception error) { + if (error != null) channel.terminate(error); + } + }); + } + stream_ids.clear(); + process_input_stream_id = null; + process = null; + } + public void onLastContextRemoved() { ILaunchConfiguration cfg = getLaunchConfiguration(); try { diff --git a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/tests/RunControl.java b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/tests/RunControl.java index 469a164b7..ddfd0deda 100644 --- a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/tests/RunControl.java +++ b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/tests/RunControl.java @@ -236,16 +236,33 @@ class RunControl { assert resume_cmds.get(id) == null; final String test_id = test_suite.getCanceledTests().get(id); if (test_id != null) { + boolean ok = false; if (enable_trace) System.out.println("" + channel_id + " cancel " + id); - IDiagnostics diag = channel.getRemoteService(IDiagnostics.class); - resume_cmds.put(id, diag.cancelTest(test_id, new IDiagnostics.DoneCancelTest() { - public void doneCancelTest(IToken token, Throwable error) { - assert resume_cmds.get(id) == token; - resume_cmds.remove(id); - if (enable_trace) System.out.println("" + channel_id + " done cancel " + error); - if (error != null && ctx_map.get(test_id) != null) exit(error); + if (rnd.nextInt(4) == 0) { + IRunControl.RunControlContext ctx = ctx_map.get(test_id); + if (ctx != null && ctx.canTerminate()) { + resume_cmds.put(id, ctx.terminate(new IRunControl.DoneCommand() { + public void doneCommand(IToken token, Exception error) { + assert resume_cmds.get(id) == token; + resume_cmds.remove(id); + if (enable_trace) System.out.println("" + channel_id + " done cancel " + error); + if (error != null && ctx_map.get(test_id) != null) exit(error); + } + })); + ok = true; } - })); + } + if (!ok) { + IDiagnostics diag = channel.getRemoteService(IDiagnostics.class); + resume_cmds.put(id, diag.cancelTest(test_id, new IDiagnostics.DoneCancelTest() { + public void doneCancelTest(IToken token, Throwable error) { + assert resume_cmds.get(id) == token; + resume_cmds.remove(id); + if (enable_trace) System.out.println("" + channel_id + " done cancel " + error); + if (error != null && ctx_map.get(test_id) != null) exit(error); + } + })); + } } else { IRunControl.RunControlContext ctx = ctx_map.get(id); |