From 4533748fa00177edac7c54672abb2cb20c3b2054 Mon Sep 17 00:00:00 2001 From: Martin Oberhuber < martin.oberhuber@windriver.com> Date: Tue, 25 Jan 2011 22:51:10 +0000 Subject: [PATCH] Bug 335059 - TerminalServiceShellOutputReader logs error when hostShell.exit() is called --- releng/org.eclipse.tm.releng/maps/rse.map | 2 +- .../shells/TerminalServiceHostShell.java | 9 ++++- .../TerminalServiceShellOutputReader.java | 39 ++++++++++++++++--- .../TerminalServiceShellWriterThread.java | 5 ++- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/releng/org.eclipse.tm.releng/maps/rse.map b/releng/org.eclipse.tm.releng/maps/rse.map index 6ee416d709b..e1ffcc6bd7f 100644 --- a/releng/org.eclipse.tm.releng/maps/rse.map +++ b/releng/org.eclipse.tm.releng/maps/rse.map @@ -39,7 +39,7 @@ plugin@org.eclipse.rse.services.files.ftp=v201101042155,:pserver:anonymous:none@ plugin@org.eclipse.rse.services.local=v201101042155,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/tools,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.local plugin@org.eclipse.rse.services.ssh=v201101101155,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/tools,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.ssh plugin@org.eclipse.rse.services.telnet=v201101042155,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/tools,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.telnet -plugin@org.eclipse.rse.services=v201101042155,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/tools,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services +plugin@org.eclipse.rse.services=v201101252250,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/tools,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services plugin@org.eclipse.rse.shells.ui=v201101042155,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/tools,,org.eclipse.tm.rse/plugins/org.eclipse.rse.shells.ui plugin@org.eclipse.rse.subsystems.files.core=v201101042155,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/tools,,org.eclipse.tm.rse/plugins/org.eclipse.rse.subsystems.files.core plugin@org.eclipse.rse.subsystems.files.dstore=v201101042155,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/tools,,org.eclipse.tm.rse/plugins/org.eclipse.rse.subsystems.files.dstore diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/shells/TerminalServiceHostShell.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/shells/TerminalServiceHostShell.java index b99845bf8e6..9c3d410b8e1 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/shells/TerminalServiceHostShell.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/shells/TerminalServiceHostShell.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2008 IBM Corporation and others. + * Copyright (c) 2006, 2011 IBM Corporation 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 @@ -20,6 +20,7 @@ * Anna Dushistova (MontaVista) - adapted from SshHostShell * Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService * Anna Dushistova (MontaVista) - [258720] SshHostShell fails to run command if initialWorkingDirectory supplied + * Rob Stryker (JBoss) - [335059] TerminalServiceShellOutputReader logs error when hostShell.exit() is called *******************************************************************************/ package org.eclipse.rse.internal.services.shells; @@ -119,6 +120,12 @@ public class TerminalServiceHostShell extends AbstractHostShell { if (fShellWriter != null) { fShellWriter.stopThread(); } + if( fStderrHandler != null ) { + fStderrHandler.stopThread(); + } + if( fStdoutHandler!= null ) { + fStdoutHandler.stopThread(); + } fTerminalShell.exit(); } diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/shells/TerminalServiceShellOutputReader.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/shells/TerminalServiceShellOutputReader.java index db8ce647c00..16364e12a43 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/shells/TerminalServiceShellOutputReader.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/shells/TerminalServiceShellOutputReader.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2008 IBM Corporation and others. + * Copyright (c) 2006, 2011 IBM Corporation 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 @@ -16,6 +16,7 @@ * Martin Oberhuber (Wind River) - Added vt100 escape sequence ignoring. * Anna Dushistova (MontaVista) - adapted from SshShellOutputReader * Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService + * Rob Stryker (JBoss) - [335059] TerminalServiceShellOutputReader logs error when hostShell.exit() is called *******************************************************************************/ package org.eclipse.rse.internal.services.shells; @@ -35,6 +36,8 @@ import org.eclipse.rse.services.shells.SimpleHostOutput; public class TerminalServiceShellOutputReader extends AbstractHostShellOutputReader { protected BufferedReader fReader; + private volatile Thread fReaderThread = null; + private volatile boolean isCanceled = false; private String fPromptChars = ">$%#]"; //Characters we accept as the end of a prompt //$NON-NLS-1$; public TerminalServiceShellOutputReader(IHostShell hostShell, @@ -50,12 +53,21 @@ public class TerminalServiceShellOutputReader extends //TODO Check if ssh supports some method of having separate stdout and stderr streams return null; } + fReaderThread = Thread.currentThread(); + try { + return interruptableReadLine(); + } finally { + fReaderThread = null; + } + } + + private IHostOutput interruptableReadLine() { StringBuffer theLine = new StringBuffer(); StringBuffer theDebugLine = null; theDebugLine = new StringBuffer(); int ch; boolean done = false; - while (!done && !isFinished()) { + while (!done && !isFinished() && !isCanceled) { try { ch = fReader.read(); switch (ch) { @@ -125,9 +137,10 @@ public class TerminalServiceShellOutputReader extends if (len>=0 && fPromptChars.indexOf(theLine.charAt(len))>=0) { waitIncrement = 5; //wait only 5 msec if we think it's a prompt } - try { - Thread.sleep(waitIncrement); - } catch (InterruptedException e) { + if (!isCanceled) { + try { + Thread.sleep(waitIncrement); + } catch (InterruptedException e) { /*ignore*/ } } if (!fReader.ready()) { done = true; @@ -137,7 +150,10 @@ public class TerminalServiceShellOutputReader extends //FIXME it's dangerous to return null here since this will end //our reader thread completely... the exception could just be //temporary, and we should keep running! - Activator.getDefault().logException(e); + if( !this.isCanceled ) { + /* 335059: Don't log IOException on close due to cancellation */ + Activator.getDefault().logException(e); + } return null; } } @@ -147,4 +163,15 @@ public class TerminalServiceShellOutputReader extends } return new SimpleHostOutput(theLine.toString()); } + + /** + * Stop the reader Thread, forcing internalReadLine() to return. + * Does not close the Stream. + */ + public void stopThread() { + this.isCanceled = true; + if (fReaderThread != null) { + fReaderThread.interrupt(); + } + } } diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/shells/TerminalServiceShellWriterThread.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/shells/TerminalServiceShellWriterThread.java index 12767ff5c2e..e1915ca4d96 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/shells/TerminalServiceShellWriterThread.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/shells/TerminalServiceShellWriterThread.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 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 @@ -9,6 +9,7 @@ * Martin Oberhuber (Wind River) - initial API and implementation * Anna Dushistova (MontaVista) - adapted from SshShellWriterThread * Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService + * Rob Stryker (JBoss) - [335059] TerminalServiceShellOutputReader logs error when hostShell.exit() is called *******************************************************************************/ package org.eclipse.rse.internal.services.shells; @@ -20,7 +21,7 @@ import java.io.PrintWriter; public class TerminalServiceShellWriterThread extends Thread { private PrintWriter fOutputWriter; private String fNextCommand; - private boolean fIsCancelled; + private volatile boolean fIsCancelled; /** * constructor for terminal service shell writer thread