Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java191
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java53
2 files changed, 165 insertions, 79 deletions
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
index 573848934..1ae6acc11 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
@@ -17,6 +17,7 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunch;
@@ -56,8 +57,9 @@ import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.IConsoleView;
-import org.eclipse.ui.console.MessageConsole;
-import org.eclipse.ui.console.MessageConsoleStream;
+import org.eclipse.ui.console.IOConsole;
+import org.eclipse.ui.console.IOConsoleInputStream;
+import org.eclipse.ui.console.IOConsoleOutputStream;
import org.eclipse.debug.ui.contexts.ISuspendTrigger;
import org.eclipse.debug.ui.contexts.ISuspendTriggerListener;
import org.eclipse.debug.ui.sourcelookup.CommonSourceNotFoundEditorInput;
@@ -128,9 +130,64 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
private final Map<String,IMemoryBlockRetrievalExtension> mem_retrieval =
new HashMap<String,IMemoryBlockRetrievalExtension>();
+
+ private class Console {
+ final String id;
+ final IOConsole console;
+ final Map<Integer,IOConsoleOutputStream> out;
+
+ Console(String id, final IOConsole console) {
+ this.id = id;
+ this.console = console;
+ out = new HashMap<Integer,IOConsoleOutputStream>();
+ process2console.put(id, this);
+ consoles.add(this);
+ Thread t = new Thread() {
+ public void run() {
+ try {
+ IOConsoleInputStream inp = console.getInputStream();
+ final byte[] buf = new byte[0x100];
+ for (;;) {
+ final int len = inp.read(buf);
+ if (len < 0) break;
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ launch.writeProcessInputStream(buf, 0, len);
+ }
+ });
+ }
+ }
+ catch (Throwable x) {
+ Activator.log("Cannot read console input", x);
+ }
+ }
+ };
+ t.setName("TCF Launch Console Input");
+ t.start();
+ }
+
+ void close() {
+ if (process2console.get(id) != this) return;
+ for (IOConsoleOutputStream stream : out.values()) {
+ try {
+ stream.close();
+ }
+ catch (IOException x) {
+ Activator.log("Cannot close console stream", x);
+ }
+ }
+ try {
+ console.getInputStream().close();
+ }
+ catch (IOException x) {
+ Activator.log("Cannot close console stream", x);
+ }
+ process2console.remove(id);
+ }
+ }
- private final Map<String,Map<Integer,MessageConsoleStream>> consoles =
- new HashMap<String,Map<Integer,MessageConsoleStream>>();
+ private final Map<String,Console> process2console = new HashMap<String,Console>();
+ private final Set<Console> consoles = new HashSet<Console>();
private static final Map<ILaunchConfiguration,IEditorInput> editor_not_found =
new HashMap<ILaunchConfiguration,IEditorInput>();
@@ -322,16 +379,9 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
private final IProcesses.ProcessesListener prs_listener = new IProcesses.ProcessesListener() {
public void exited(String process_id, int exit_code) {
- Map<Integer,MessageConsoleStream> streams = consoles.get(process_id);
- if (streams!= null) {
- for (MessageConsoleStream stream : streams.values()) {
- try {
- stream.close();
- }
- catch (IOException x) {
- Activator.log("Cannot close console stream", x);
- }
- }
+ Console console = process2console.get(process_id);
+ if (console != null) {
+ console.close();
onLastContextRemoved();
}
}
@@ -413,44 +463,51 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
try {
IProcesses.ProcessContext prs = launch.getProcessContext();
if (prs == null || !process_id.equals(prs.getID())) return;
- Map<Integer,MessageConsoleStream> streams = consoles.get(process_id);
- if (streams == null) consoles.put(process_id, streams = new HashMap<Integer,MessageConsoleStream>());
- MessageConsoleStream stream = streams.get(stream_id);
+ Console console = process2console.get(process_id);
+ if (console == null) {
+ final IOConsole c = new IOConsole("TCF " + process_id, null,
+ ImageCache.getImageDescriptor(ImageCache.IMG_TCF), "UTF-8", true);
+ display.asyncExec(new Runnable() {
+ public void run() {
+ try {
+ IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
+ manager.addConsoles(new IConsole[]{ c });
+ IWorkbenchWindow w = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (w == null) return;
+ IWorkbenchPage page = w.getActivePage();
+ if (page == null) return;
+ IConsoleView view = (IConsoleView)page.showView(IConsoleConstants.ID_CONSOLE_VIEW);
+ view.display(c);
+ }
+ catch (Throwable x) {
+ Activator.log("Cannot open console view", x);
+ }
+ }
+ });
+ console = new Console(process_id, c);
+ }
+ IOConsoleOutputStream stream = console.out.get(stream_id);
if (stream == null) {
- MessageConsole console = null;
- for (MessageConsoleStream s : streams.values()) console = s.getConsole();
- if (console == null) {
- final MessageConsole c = console = new MessageConsole("TCF " + process_id,
- ImageCache.getImageDescriptor(ImageCache.IMG_TCF));
- final MessageConsoleStream s = stream = console.newMessageStream();
- display.asyncExec(new Runnable() {
- public void run() {
- try {
- int color_id = SWT.COLOR_BLACK;
- switch (stream_id) {
- case 1: color_id = SWT.COLOR_RED; break;
- case 2: color_id = SWT.COLOR_BLUE; break;
- case 3: color_id = SWT.COLOR_GREEN; break;
- }
- s.setColor(display.getSystemColor(color_id));
- IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
- manager.addConsoles(new IConsole[]{ c });
- IWorkbenchWindow w = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
- if (w == null) return;
- IWorkbenchPage page = w.getActivePage();
- if (page == null) return;
- IConsoleView view = (IConsoleView)page.showView(IConsoleConstants.ID_CONSOLE_VIEW);
- view.display(c);
- }
- catch (Throwable x) {
- Activator.log("Cannot open console view", x);
+ final IOConsoleOutputStream s = stream = console.console.newOutputStream();
+ display.asyncExec(new Runnable() {
+ public void run() {
+ try {
+ int color_id = SWT.COLOR_BLACK;
+ switch (stream_id) {
+ case 1: color_id = SWT.COLOR_RED; break;
+ case 2: color_id = SWT.COLOR_BLUE; break;
+ case 3: color_id = SWT.COLOR_GREEN; break;
}
+ s.setColor(display.getSystemColor(color_id));
}
- });
- }
- streams.put(stream_id, stream);
+ catch (Throwable x) {
+ Activator.log("Cannot open console view", x);
+ }
+ }
+ });
+ console.out.put(stream_id, stream);
}
- stream.print(new String(data, 0, data.length, "UTF-8"));
+ stream.write(data, 0, data.length);
}
catch (Throwable x) {
Activator.log("Cannot write to console", x);
@@ -508,8 +565,8 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
private void onLastContextRemoved() {
Protocol.invokeLater(1000, new Runnable() {
public void run() {
- for (Map<Integer,MessageConsoleStream> streams : consoles.values()) {
- for (MessageConsoleStream stream : streams.values()) {
+ for (Console console : consoles) {
+ for (IOConsoleOutputStream stream : console.out.values()) {
if (!stream.isClosed()) return;
}
}
@@ -535,29 +592,23 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
refreshLaunchView();
}
}
-
+
void dispose() {
- final HashSet<MessageConsole> set = new HashSet<MessageConsole>();
- for (Map<Integer,MessageConsoleStream> streams : consoles.values()) {
- for (MessageConsoleStream stream : streams.values()) {
- set.add(stream.getConsole());
- if (!stream.isClosed()) {
- try {
- stream.close();
- }
- catch (IOException x) {
- Activator.log("Cannot close console stream", x);
- }
- }
+ if (!consoles.isEmpty()) {
+ int i = 0;
+ final IOConsole[] buf = new IOConsole[consoles.size()];
+ for (Console console : consoles) {
+ console.close();
+ buf[i++] = console.console;
}
+ consoles.clear();
+ display.asyncExec(new Runnable() {
+ public void run() {
+ IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
+ manager.removeConsoles(buf);
+ }
+ });
}
- consoles.clear();
- display.asyncExec(new Runnable() {
- public void run() {
- IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
- manager.removeConsoles(set.toArray(new MessageConsole[set.size()]));
- }
- });
}
void addNode(String id, TCFNode node) {
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
index 9190c1de2..1f12f0565 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
@@ -78,6 +78,7 @@ public class TCFLaunch extends Launch {
private boolean last_context_exited;
private ProcessContext process;
private IToken process_start_command;
+ private String process_input_stream_id;
private int context_action_cnt;
private final HashMap<String,LinkedList<Runnable>> context_action_queue =
@@ -384,14 +385,15 @@ public class TCFLaunch extends Launch {
}
private void connectProcessStreams() {
+ assert process_start_command == null;
final IStreams streams = getService(IStreams.class);
if (streams == null) return;
final String inp_id = (String)process.getProperties().get(IProcesses.PROP_STDIN_ID);
final String out_id = (String)process.getProperties().get(IProcesses.PROP_STDOUT_ID);
final String err_id = (String)process.getProperties().get(IProcesses.PROP_STDERR_ID);
- for (final String id : stream_ids) {
+ for (final String id : stream_ids.toArray(new String[stream_ids.size()])) {
if (id.equals(inp_id)) {
- // TODO: process input stream handling
+ process_input_stream_id = id;
}
else if (id.equals(out_id)) {
connectStream(id, 0);
@@ -409,15 +411,15 @@ public class TCFLaunch extends Launch {
final String peocess_id = process.getID();
final IStreams streams = getService(IStreams.class);
IStreams.DoneRead done = new IStreams.DoneRead() {
- boolean canceled;
+ boolean disconnected;
public void doneRead(IToken token, Exception error, int lost_size, byte[] data, boolean eos) {
- if (canceled) return;
+ if (disconnected) return;
// TODO: handle process output data loss
if (data != null && data.length > 0) {
for (Listener l : listeners) l.onProcessOutput(TCFLaunch.this, peocess_id, no, data);
}
if (eos || error != null) {
- canceled = true;
+ disconnected = true;
// TODO: report error reading process output
disconnectStream(id);
return;
@@ -432,6 +434,7 @@ public class TCFLaunch extends Launch {
}
private void disconnectStream(String id) {
+ stream_ids.remove(id);
if (channel.getState() != IChannel.STATE_OPEN) return;
IStreams streams = getService(IStreams.class);
streams.disconnect(id, new IStreams.DoneDisconnect() {
@@ -488,13 +491,47 @@ public class TCFLaunch extends Launch {
return process;
}
+ public void writeProcessInputStream(byte[] buf, int pos, int len) {
+ assert Protocol.isDispatchThread();
+ if (channel.getState() != IChannel.STATE_OPEN) return;
+ if (process_input_stream_id == null) return;
+ IStreams streams = getService(IStreams.class);
+ if (streams == null) return;
+ streams.write(process_input_stream_id, buf, pos, len, new IStreams.DoneWrite() {
+ public void doneWrite(IToken token, Exception error) {
+ // TODO: stream write error handling
+ }
+ });
+ }
+
public boolean isConnecting() {
return connecting;
}
public void onLastContextRemoved() {
last_context_exited = true;
- channel.close();
+ closeChannel();
+ }
+
+ public void closeChannel() {
+ assert Protocol.isDispatchThread();
+ if (channel == null) return;
+ if (channel.getState() == IChannel.STATE_CLOSED) return;
+ IStreams streams = getService(IStreams.class);
+ final Set<IToken> cmds = new HashSet<IToken>();
+ for (String id : stream_ids) {
+ cmds.add(streams.disconnect(id, new IStreams.DoneDisconnect() {
+ public void doneDisconnect(IToken token, Exception error) {
+ cmds.remove(token);
+ if (channel.getState() == IChannel.STATE_CLOSED) return;
+ if (error != null) channel.terminate(error);
+ else if (cmds.isEmpty()) channel.close();
+ }
+ }));
+ }
+ stream_ids.clear();
+ process_input_stream_id = null;
+ if (cmds.isEmpty()) channel.close();
}
public IPeer getPeer() {
@@ -519,9 +556,7 @@ public class TCFLaunch extends Launch {
try {
Protocol.invokeLater(new Runnable() {
public void run() {
- if (channel != null && channel.getState() != IChannel.STATE_CLOSED) {
- channel.close();
- }
+ closeChannel();
}
});
}

Back to the top