? patch#58935.diff Index: ExternalCommand.java =================================================================== RCS file: /cvs/vcscore/src/org/netbeans/modules/vcscore/cmdline/exec/ExternalCommand.java,v retrieving revision 1.40 diff -u -r1.40 ExternalCommand.java --- ExternalCommand.java 14 Mar 2005 11:58:21 -0000 1.40 +++ ExternalCommand.java 15 May 2005 18:53:11 -0000 @@ -450,12 +450,9 @@ } private class OutputGrabber extends Object implements SafeRunnable { - - private static final int LINE_LENGTH = 80; - private static final int BUFF_LENGTH = 512; - - private InputStreamReader stdout; - private InputStreamReader stderr; + + private BufferedReader stdout; + private BufferedReader stderr; // Variables indicating EOF of command's output streams. // They are needed only for the OpenVMS & OS/2 patch. @@ -465,13 +462,10 @@ private boolean shouldStop = false; private boolean stopped = false; private boolean finished = false; - private StringBuffer outBuffer = new StringBuffer(LINE_LENGTH); - private StringBuffer errBuffer = new StringBuffer(LINE_LENGTH); - private char[] buff = new char[BUFF_LENGTH]; public OutputGrabber(InputStream stdout, InputStream stderr) { - this.stdout = new InputStreamReader(stdout); - this.stderr = new InputStreamReader(stderr); + this.stdout = new BufferedReader(new InputStreamReader(stdout)); + this.stderr = new BufferedReader(new InputStreamReader(stderr)); } /** Stop the grabber */ @@ -489,20 +483,10 @@ /** Whether the grabber is stopped. If yes, should be flushed and garbage-collected. */ public boolean isStopped() { - try { - //if (shouldStop && !stdout.ready() && !stderr.ready()) stopped = true; - // If the OS is OpenVMS or OS/2, we want to stop only if EOF has been reached on both output streams - if (osType != Utilities.OS_VMS && osType != Utilities.OS_OS2) { - if (shouldStop && !stdout.ready() && !stderr.ready()) stopped = true; - } else { - if (shouldStop && eof_stdout && eof_stderr) { - stopped = true; - } else { - stopped = false; - } - } - } catch (IOException ioexc) { + if (shouldStop && eof_stdout && eof_stderr) { stopped = true; + } else { + stopped = false; } return stopped; } @@ -513,97 +497,52 @@ wait(); } } - } - - /** Whether there is some output to grab */ - public boolean hasOutput() { - boolean has; - try { - //has = stdout.ready() || stderr.ready(); - // If the OS is OpenVMS or OS/2, just assume there is output available - if (osType != Utilities.OS_VMS && osType != Utilities.OS_OS2) { - has = stdout.ready() || stderr.ready(); - } else { - has = true; - } - } catch (IOException ioexc) { - has = false; - } - return has; - } + } /** Run the grabbing. It grabbs some of the output, needs to be invoked periodically intil it's not stopped. */ public void run() { - int n = 0; + final BufferedReader err = stderr; + final BufferedReader out = stdout; + + Thread errThread = new Thread(new Runnable() { + public void run() { + try { + String line; + while ((line = err.readLine()) != null) { + stderrNextLine(line); + } + } catch (IOException ie) {} + } + } + ); + + Thread outThread = new Thread(new Runnable() { + public void run() { + try { + String line; + while ((line = out.readLine()) != null) { + stdoutNextLine(line); + } + } catch (IOException ie) {} + } + } + ); + outThread.start(); + errThread.start(); try { - //if (stdout.ready() && (n = stdout.read(buff, 0, BUFF_LENGTH)) > -1) { - // For OpenVMS and OS/2, we need to see EOF before we're sure we've grabbed all output - if (((osType == Utilities.OS_VMS || osType == Utilities.OS_OS2) && !eof_stdout) || stdout.ready()) { - n = stdout.read(buff, 0, BUFF_LENGTH); - } - if (n > -1) { - for (int i = 0; i < n; i++) { - if (buff[i] == '\n') { - try { - stdoutNextLine(outBuffer.toString()); - } finally { - outBuffer.delete(0, outBuffer.length()); - } - } else { - if (buff[i] != 13) { - outBuffer.append(buff[i]); - } - } - } - //if (n > 0) System.out.println("IMMEDIATE OUT("+n+") = '"+new String(buff, 0, n)+"'"); - if (n > 0 && isImmediateOut) { - synchronized (stdOutLock) { - Iterator it = stdImmediateOutListeners.iterator(); - while(it.hasNext()) { - ((TextOutputListener) it.next()).outputLine(new String(buff, 0, n)); - } - } - } - } else { - stopped = true; - eof_stdout = true; - } - //if (stderr.ready() && (n = stderr.read(buff, 0, BUFF_LENGTH)) > -1) { - n = 0; - // For OpenVMS and OS/2, we need to see EOF before we're sure we've grabbed all output - if (((osType == Utilities.OS_VMS || osType == Utilities.OS_OS2) && !eof_stderr) || stderr.ready()) { - n = stderr.read(buff, 0, BUFF_LENGTH); - } - if (n > -1) { - for (int i = 0; i < n; i++) { - if (buff[i] == '\n') { - try { - stderrNextLine(errBuffer.toString()); - } finally { - errBuffer.delete(0, errBuffer.length()); - } - } else { - if (buff[i] != 13) { - errBuffer.append(buff[i]); - } - } - } - //if (n > 0) System.out.println("IMMEDIATE ERR("+n+") = '"+new String(buff, 0, n)+"'"); - if (n > 0 && isImmediateErr) { - synchronized (stdErrLock) { - Iterator it = stdImmediateErrListeners.iterator(); - while(it.hasNext()) { - ((TextOutputListener) it.next()).outputLine(new String(buff, 0, n)); - } - } - } - } else { - stopped = true; - eof_stderr = true; - } - } catch (IOException ioexc) { + outThread.join(); + } catch (InterruptedException ie) { + } finally { + stopped = true; + eof_stdout = true; + } + try { + errThread.join(); + } catch (InterruptedException ie) { + } finally { stopped = true; + eof_stderr = true; } } @@ -616,17 +555,11 @@ try { stderr.close(); } catch (IOException ioexc1) {} - // Grab any remaining output - run(); - // Flush it - try { - if (outBuffer.length() > 0) stdoutNextLine(outBuffer.toString()); - if (errBuffer.length() > 0) stderrNextLine(errBuffer.toString()); - } finally { - finished = true; - synchronized (this) { - notifyAll(); - } + + finished = true; + + synchronized (this) { + notifyAll(); } } @@ -663,11 +596,9 @@ OutputGrabber output = (OutputGrabber) outputGrabbers.get(i); //System.out.println(" output("+i+"): isStopped() = "+output.isStopped()+", hasOutput() = "+output.hasOutput()); if (!output.isStopped()) { - if (output.hasOutput()) { - output.run(); - processed = true; - outputProducers.add(output); - } + output.run(); + processed = true; + outputProducers.add(output); } else { output.flush(); outputGrabbers.remove(i);