Ticket UUID: | 478856 | |||
Title: | Fileevents not always generated | |||
Type: | Bug | Version: | None | |
Submitter: | stwo | Created on: | 2001-11-06 20:44:25 | |
Subsystem: | 25. Channel System | Assigned To: | andreas_kupries | |
Priority: | 6 | Severity: | ||
Status: | Closed | Last Modified: | 2001-11-07 11:49:04 | |
Resolution: | Fixed | Closed By: | andreas_kupries | |
Closed on: | 2001-11-07 04:49:04 | |||
Description: |
Code examples in this message are Tcl-pseudocode. Read incoming with: read $channel $read_amount Send outgoing with: if {buffering == none} { puts -nonewline $channel $msg\n } else if {buffering == full} { puts $channel $msg flush $channel } Conditions: send_amount = [string length $msg] read_amount < send_amount < buffersize (important) encoding != binary translation = ? buffering = see above In this situation, the program will not always get fileevents. An independent [read $channel 1] seems to unblock everything, and the program will keep getting fileevents until it has consumed all the data from the buffer. If this is a bug of some sort and not my fault and isn't already on SF (I checked but didn't see anything like it), then I'm guessing it hasn't been found because there are very few programs reading from channels in this manner. The ones I have looked at so far either use [gets], or [read read_amount] where read_amount == buffersize. I am using sockets. This bit of (serial) code on the Wiki will also exhibit this behaviour. http://mini.net/tcl/1885.html All these tests exhibited this behaviour. In each case, the test was performed with one end acting as the server, and then again with the other end acting as the server. Tcl8.3.3 Win95 -. Win95 (localhost) WinNT - WinNT (localhost) Win95 - WinNT (net) WinNT - WinNT (net) WinNT - WinNT (serial - 2 machines) Win95 - Linux 2.2.18 (net) Linux 2.2.18 - Linux 2.2.18 (localhost) Tcl8.4a3 Linux 2.2.18 - Linux 2.2.18 (localhost) --------------- Notes on [puts]: buffering == none [puts $data] != [puts -nonewline $data\n] buffering == full [puts $data] == [puts -nonewline $data\n] According to the man page, [puts] without '-nonewline' will *output* a newline after whatever it's supposed to output. The key word here is *output*. If buffering is set to none, there can be two actual 'output operations'. One for [puts]'s string, one for the newline. If the channel on the receiving has set up a [fileevent readable], it can be called twice, once for [puts]'s string, once for the newline. However, a [puts -nonewline $msg\n] will result in only one output operation,and one fileevent on the receiving end. This is with buffering == full. Looking at the Tcl source, the way this is done is makes sense to me, perhaps something should be added to the man page to clarify. I know that it's possible for the message to be broken up, and for the receiver to get any number of fileevents. But it seems that I will always get at least one extra fileevent where the newline could have been part of the prior fileevent. I was a bit confused by my program's behaviour until I worked this out. | |||
User Comments: |
andreas_kupries added on 2001-11-07 11:49:04:
Logged In: YES user_id=75003 Patch committed to both HEAD and core-8-3-1-branch (8.3.4+). andreas_kupries added on 2001-11-07 05:38:10: File Added - 12940: io.diff andreas_kupries added on 2001-11-07 05:38:09: Logged In: YES user_id=75003 Enclosed a possible fix. It passes the testsuite on Linux, and the example script behaves properly. The line numbers are bit off because of my 'printf' statements in tclIO.c (I removed a number of chunks containing only debug code from the original diff). stwo added on 2001-11-07 03:44:26: File Added - 12935: qsc.tcl |