Tcl Source Code

View Ticket
Login
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

Attachments: