Ticket UUID: | 525783 | |||
Title: | Need optional full flush on [exit] for serial | |||
Type: | RFE | Version: | None | |
Submitter: | dgp | Created on: | 2002-03-05 04:03:07 | |
Subsystem: | 25. Channel System | Assigned To: | ferrieux | |
Priority: | 5 Medium | Severity: | ||
Status: | Closed | Last Modified: | 2012-07-04 04:34:55 | |
Resolution: | Fixed | Closed By: | ferrieux | |
Closed on: | 2012-07-03 21:33:02 | |||
Description: |
Previously reported as Tk Bug 525778, tclsh has the same problem on Solaris 8: # FILE: test.tcl for {set i 0} {$i < [lindex $argv 0]} {incr i} { puts $i } $ tclsh8.3 test.tcl 5 0 1 2 3 4 $ tclsh8.4 test.tcl 5 <no output> $ tclsh8.3 test.tcl 500 0 ... 499 $ tclsh8.4 test.tcl 5 0 ... 358 $ I'm assigning to "Channel System" because I think that must be where the bug lies. tclsh calls Tcl_FSEvalFile() within Tcl_Main() and wish calls Tcl_EvalFile() within Tk_Main(), so they don't have code in common, but show the same misbehavior. | |||
User Comments: |
ferrieux added on 2012-07-04 04:34:55:
Hum, 398 of course, not 348. ferrieux added on 2012-07-04 04:33:02: OK, closing as fixed by TIP 348: those who want the data to be flushed with insistence on serial lines (possibly blocking for a long time) should set the channel to blocking mode prior to closing/exiting; those who want a timely exit at the cost of possible data loss should set it to nonblocking mode. dkf added on 2012-07-04 02:59:17: Probably not, other than that compared to everything else they are horribly slow so people _never_ seem to agree on whether to block for them to flush on exit or not. If you think this FRQ is superseded, just close it. :-) ferrieux added on 2012-07-03 22:34:43: IMO, the "-closemode" of TIP 160 is obsoleted by TIP 398, simply by switching the (serial) channel to blocking or nonblocking before closing. Am I missing something linked with the special nature of serial lines ? dkf added on 2012-07-03 15:26:17: IP - Comment Removed: 130.88.1.31 dkf added on 2012-07-03 15:25:57: IP - Comment Removed: 130.88.1.31 dkf added on 2012-07-03 15:25:47: IP - Comment Removed: 130.88.1.31 dkf added on 2012-07-03 15:25:25: This appears to be entangled with TIP #398 concerns... davygrvy added on 2005-11-06 05:50:35: Logged In: YES user_id=7549 Pat, please help, I can't do Tcl programming stuff at this time.. dkf added on 2003-10-22 22:27:03: Logged In: YES user_id=79902 Dropping the prio; it's in the TIP process now dkf added on 2003-10-17 17:46:25: Logged In: YES user_id=79902 See TIP#160 http://purl.org/tcl/tip/160 dgp added on 2002-06-25 21:34:07: Logged In: YES user_id=80530 restored assignements lost in Tracker move. dkf added on 2002-06-25 21:30:20: Logged In: YES user_id=79902 This is really an FRQ now schroedter added on 2002-06-24 18:08:44: Logged In: YES user_id=99573 As the author of the recent serial port changes (TIP#35) I'm supporting Donal's proposal of an additional fconfigure option: fconfigure $fd -onclose wait/discard This option should be general for *all* Tcl channels with the obvious default=wait (or flush). Please note that this cannot be done by the channel driver's [fconfigure] part because the channels driver cannot easily distinguish between a "normal flush" and a "flush-on-close" situation. Currently Tcl's channel system performs a blocking write before closing/exiting - Put the channel into blocking mode and - Write out all pending data This should be avoided by calling [fconfigure $chan -onclose discard]. It's really bad that a channel intentionally configured by the user as non-blocking becomes blocking at close. I assume that this could also be useful for other channels (sockets ?). Rolf. dkf added on 2002-06-24 17:08:30: Logged In: YES user_id=79902 The current situation results in bugs for the smallest number of people; a lot more people use Tcl from a terminal on Unix than use serial ports under Unix! A comment of mine below (the -onclose option) contains the germ of a TIP to fully resolve this matter (I know of no way to determine what the best action is by default, and that is really an OS design decision that I agree with in principle, so this really belongs in the hands of programmers) and I might get around to doing something about it in the future. Or I might not. Either way, no reason to hold back the b1 release waiting on this. dgp added on 2002-06-22 07:30:04: Logged In: YES user_id=80530 hot potato back to you. all my problems are resolved. andreas_kupries added on 2002-06-22 00:23:54: Logged In: YES user_id=75003 In a way. See below. Jeff did provide and commit a fix, but he is not completely satisfied with it. The std* channels have the correct behaviour, but true serial channels might not get completely auto-flushed when exiting. So the bug as reported is fixed, with problems in a different area. dgp added on 2002-06-22 00:03:42: Logged In: YES user_id=80530 I can no longer reproduce the problem with the HEAD sources. Is this matter closed? andreas_kupries added on 2002-05-11 00:05:10: Logged In: YES user_id=75003 I remember that Jeff did some changes ... Changelog ... 2002-03-05 Jeff Hobbs <[email protected]> * unix/tclUnixChan.c: initial remedy for [Bug #525783] flush problem introduced by TIP #35. This may not satisfy true serial channels, but it restores the correct flushing of std* channels on exit. dgp added on 2002-05-10 23:53:05: Logged In: YES user_id=80530 Did this get resolved? dkf added on 2002-03-06 20:18:16: Logged In: YES user_id=79902 The problem with tcflush on exit is that it can nuke output in the OS buffers that came from stderr (say "sayonara" to debugging messages!) Further investigation found that this could still happen even with some fairly elaborate measures to prevent it (like barring tcflush from operating on FDs 0, 1 and 2) because it is a race between the data being grabbed by the tty and displayed, and the tcflush on an unrelated channel (you'll need the [open [exec tty]] addition mentioned below to enable this behaviour.) So as to make sure that people just using Tcl normally would not see the problem, and given the short timescale we were working on w.r.t. the 8.4a4 release, the tcflush was changed to a tcdrain (whose behaviour meets more what non-serial people think of by a flush!) even though this is clearly not what you were intending when you wrote the code. A better fix will require application-input (since both behaviours are right in certain circumstances) which means there's room for another thing to [fconfigure], e.g. fconfigure $fd -onclose wait/discard (Reset semantics probably ought to be handled in the same way, because they are equally surprising when they hit the controlling terminal and both styles of behaviour can be considered to be correct in some circumstances.) schroedter added on 2002-03-06 19:48:52: Logged In: YES user_id=99573 This problem was probably introduced by two changes: 1. stdin/stdout are now handled by the TTY driver 2. The TIP#35 changes (Add serial port handshake support) There is no doubt, that TCL-exit should not stall if a serial port output is blocked. This can happen with handshake support. This could also happen even before the TIP#35 changes, when the serial port handshake is activated by using "stty" settings. At exit the channel driver sets all unflushed channels to blocking mode and waits until the output is flushed (maybe forever). That's why the serial port driver now calls "tcflush". For a serial port this is okay, for stdin/stdout this maybe bad. Anyway Tcl's behaviour on exit needs further discussion. hobbs added on 2002-03-06 04:01:49: File Added - 18840: 525783.patch hobbs added on 2002-03-06 04:01:48: Logged In: YES user_id=72656 Attached is my recommend patch (already commited for others to test) to 8.4a4. This removes use of tcflush and reverts to always calling FileOutputProc for now. hobbs added on 2002-03-06 03:07:58: Logged In: YES user_id=72656 A much more reliable test script is: set size [lindex $argv 0] if {![string is int -strict $size]} { set size 100 } for {set i 0} {$i < $size} {incr i} { puts $i } puts stderr done by adding in the data on the extra channel, that seems to add enough perturbation to the tty's to always show the bug. However, simply changing "tcflush(...)" to "tcdrain((fd))" solves all the problems that I can repeat. dkf added on 2002-03-05 23:46:33: Logged In: YES user_id=79902 However, things still foul up if you add open [exec tty] to the script. Need fstat() to detect and avoid that. :^( dkf added on 2002-03-05 23:40:48: File Deleted - 18826: File Added - 18835: flush3.patch dkf added on 2002-03-05 23:40:47: Logged In: YES user_id=79902 That was only a partial fix; here's a better one dkf added on 2002-03-05 18:22:28: File Added - 18826: flush.patch dkf added on 2002-03-05 18:22:27: Logged In: YES user_id=79902 Easy fix: exclude stdout and stderr from the magical flushing in TtyCloseProc() using the attached patch. dkf added on 2002-03-05 16:50:09: Logged In: YES user_id=79902 This looks to be TIP#35 related (which stopped serial lines from being flushed on [close] because the operation might block indefinitely), combined with other changes which made stdio channels be recognised as serial channels when used interactively. Both of these make perfect sense in themselves, but they interact badly. Yuck. I suppose the correct thing to do is to do the flush on close only for stdio channels to ttys; i.e. when the fd is 1 or 2... dgp added on 2002-03-05 13:29:21: Logged In: YES user_id=80530 Confirmed. The changes to unix/tclUnixChan.c on 2002-Feb-27 are what broke things. If this can't be fixed quickly, I recommend reverting to Revision 1.29 before releasing 8.4a4. dgp added on 2002-03-05 12:55:14: Logged In: YES user_id=80530 Sources on Feb 15 worked fine too. This is a recently introduced issue. dgp added on 2002-03-05 11:35:27: Logged In: YES user_id=80530 tclsh 8.4a3 works properly, so the bug has been introduced since that release. |
