Re: [tcljava-dev] PATCH: stdout flushing, mods for Swank
Brought to you by:
mdejong
From: Mo D. <md...@un...> - 2003-03-05 23:22:18
|
On Sun, 30 Jun 2002 23:00:21 -0600 Tom Poindexter <tpo...@ny...> wrote: > Here's a patch that is similar in function to Shawn Boyce's recent > patch, but works by only causing a flush on stdout when it is attached > to a tty. Shawn's patch causes a flush for every puts on every file, which > seems a little heavy handed. I ended up doing the following: 1. Flush stdout when in line buffering mode and a \n is the last char of the data. 2. Invoke close() for each channel when tearing down an interp. 3. Invoke flush() one last time from the close method for StdChannel 4. Remove the extra buffering for stderr and stdout The following two patches implement these changes. Index: ChangeLog =================================================================== RCS file: /cvsroot/tcljava/tcljava/ChangeLog,v retrieving revision 1.224 diff -u -r1.224 ChangeLog --- ChangeLog 14 Feb 2003 23:26:56 -0000 1.224 +++ ChangeLog 5 Mar 2003 22:54:32 -0000 @@ -1,3 +1,12 @@ +2003-03-05 Mo DeJong <md...@us...> + + * src/jacl/tcl/lang/StdChannel.java (open, write): + Avoid wrapping a buffered IO object around the + stdio and stderr streams since this was causing + problems where stdout was not being flushed. + Instead, explicitly handle flushing in the + write method. + 2003-02-14 Mo DeJong <md...@us...> * Makefile.in: Build a jar file named hello.jar Index: src/jacl/tcl/lang/StdChannel.java =================================================================== RCS file: /cvsroot/tcljava/tcljava/src/jacl/tcl/lang/StdChannel.java,v retrieving revision 1.16 diff -u -r1.16 StdChannel.java --- src/jacl/tcl/lang/StdChannel.java 23 Jan 2002 09:53:49 -0000 1.16 +++ src/jacl/tcl/lang/StdChannel.java 5 Mar 2003 22:54:32 -0000 @@ -97,19 +97,11 @@ mode = TclIO.WRONLY; setBuffering(TclIO.BUFF_LINE); setChanName("stdout"); - if (writer == null) { - writer = new BufferedWriter( - new OutputStreamWriter(System.out)); - } break; case STDERR: mode = TclIO.WRONLY; setBuffering(TclIO.BUFF_NONE); setChanName("stderr"); - if (writer == null) { - writer = new BufferedWriter( - new OutputStreamWriter(System.err)); - } break; default: throw new RuntimeException( @@ -133,13 +125,18 @@ void write(Interp interp, TclObject outData) throws IOException, TclException { - super.write(interp, outData); + checkWrite(interp); - // The OutputStreamWriter class will buffer even if you don't - // wrap it in a BufferedWriter. The stderr file object must - // not require an explicit flush so we just hack a flush in. - if (stdType == STDERR) - flush(interp); + if (stdType == STDERR) { + System.err.print(outData.toString()); + } else { + String s = outData.toString(); + System.out.print(s); + if (buffering == TclIO.BUFF_NONE || + (buffering == TclIO.BUFF_LINE && s.endsWith("\n"))) { + System.out.flush(); + } + } } String getChanType() { Index: ChangeLog =================================================================== RCS file: /cvsroot/tcljava/tcljava/ChangeLog,v retrieving revision 1.225 diff -u -r1.225 ChangeLog --- ChangeLog 5 Mar 2003 22:57:54 -0000 1.225 +++ ChangeLog 5 Mar 2003 23:18:21 -0000 @@ -1,3 +1,14 @@ +2003-03-05 Tom Poindexter <tpo...@ny...>, + Mo DeJong <md...@us...> + + * src/jacl/tcl/lang/Interp.java (eventuallyDispose): + * src/jacl/tcl/lang/StdChannel.java (close): Invoke + the close() method for any remaining channel + when the interp is being disposed of. The close + method in the StdChannel class will invoke flush + one final time for stdout in case there was output + that had not yet been flushed. + 2003-03-05 Mo DeJong <md...@us...> * src/jacl/tcl/lang/StdChannel.java (open, write): Index: src/jacl/tcl/lang/Interp.java =================================================================== RCS file: /cvsroot/tcljava/tcljava/src/jacl/tcl/lang/Interp.java,v retrieving revision 1.41 diff -u -r1.41 Interp.java --- src/jacl/tcl/lang/Interp.java 9 Jan 2003 02:15:39 -0000 1.41 +++ src/jacl/tcl/lang/Interp.java 5 Mar 2003 23:18:23 -0000 @@ -542,6 +542,18 @@ } } + // Close any remaining channels + + for (Enumeration e = interpChanTable.keys(); e.hasMoreElements();) { + Object key = e.nextElement(); + Channel chan = (Channel) interpChanTable.get(key); + try { + chan.close(); + } catch (IOException ex) { + // Ignore any IO errors + } + } + // Finish deleting the global namespace. // FIXME : check impl of Tcl_DeleteNamespace Index: src/jacl/tcl/lang/StdChannel.java =================================================================== RCS file: /cvsroot/tcljava/tcljava/src/jacl/tcl/lang/StdChannel.java,v retrieving revision 1.17 diff -u -r1.17 StdChannel.java --- src/jacl/tcl/lang/StdChannel.java 5 Mar 2003 22:57:59 -0000 1.17 +++ src/jacl/tcl/lang/StdChannel.java 5 Mar 2003 23:18:23 -0000 @@ -139,6 +139,18 @@ } } + /** + * Check for any output that might still need to be flushed + * when the channel is closed. + */ + + void close() throws IOException { + super.close(); + + if (stdType == STDOUT) + System.out.flush(); + } + String getChanType() { return "tty"; } cheers Mo DeJong |