Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2011-11-28 16:35:06 +0000
committerEugene Tarassov2011-11-28 16:35:06 +0000
commitbec08e6e0af73f33c0fc57ac7b441a39e1c20672 (patch)
treec11d36d847abd2e175b60d4ea3867d2d0b470fdd
parent32ef6d7f15016a690e8c0dea6bef284c90abbd9b (diff)
downloadorg.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.
-rw-r--r--plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/internal/services/remote/RunControlProxy.java9
-rw-r--r--plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/services/IRunControl.java26
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/detach.gifbin0 -> 883 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/plugin.properties1
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/plugin.xml13
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/DetachCommand.java76
-rw-r--r--plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java20
-rw-r--r--plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/tests/RunControl.java33
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
new file mode 100644
index 000000000..2f875e2da
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/detach.gif
Binary files differ
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);

Back to the top