Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo


#2 Need to split bidirectional channels (sockets; pipes or devi


OriginalBugID: 1429 RFE
Version: 8.0.4
SubmitDate: '1999-03-04'
LastModified: '2000-05-04'
Severity: SER
Status: Assigned
Submitter: pat
ChangedBy: hobbs
RelatedBugIDs: 5339
OS: Other
Machine: NA
FixedDate: '2000-10-25'
ClosedDate: '2000-10-25'

Alexandre FERRIEUX

The Tcl Channel model is a useful abstraction, that effectively tries to
wipe out many OS peculiarities. However, the particular case of
"bidirectional" channels (e.g. pipes in "r+" mode) is somewhat tricky:
in this case a single channel hides *two* OS-level descriptors/handles.
The problem is that most configuration operations apply to both
simultaneously, which is not always wanted.
For example, [fconfigure -blocking 0] cannot be told to only the write
side of an r+ pipe. Also, as already noted on clt, you cannot close only
the write side, so that the child gets an EOF, then listen to its last
words on the read side: both are closed at the same time. A slightly
different case is that of sockets, which are indeed made of a single
bidirectional descriptor. Still, it would be very useful (for the same
reasons) to be able to issue a half-close, as is possible with the
shutdown() syscall.

Proposed unified syntax for this extension: a "-readside/-writeside"
option to the [close] and [fconfigure] commands.

5339 discusses the separation of r/w for close.
-- 05/04/2000 hobbs


    • priority: 5 --> 6
    • milestone: 102416 --> 102413
  • Don Porter
    Don Porter

    • labels: 104250 --> 322368
    • assigned_to: nobody --> andreas_kupries
    • labels: 322368 --> 25. Channel System
    • milestone: 102413 -->
  • Close2Proc for sockets (win and unix)

  • Switching this to Patch tracker, to hold beginning of implementation of the request, which is now TIP 332.

    This first patch just brings the close2proc to the socket channel type.
    The only other type-specific close2proc foreseen as useful for this TIP is for pipes, and already exists.
    The next missing part is in the generic layer. Andreas, I'm counting on you there ;-)

    File Added: halfclosesock.patch

  • halfclosesock + Tcl_CloseEx + Tcl-level close read|write, diff -wu, DRAFT. Compiles, untested

  • updated patch with implementation for 'close' command, and Tcl_CloseEx glue code. Draft. Compiles on my test. No test at all. Likely to crash.

  • First a minor thing: replace objv[3] by objv[2] for the direction argument in Tcl_CloseObjCmd (segfault ;-)
    Now, more worrisome: half-close (w) on a socket actually does a full close: the channel is de-registered:

    % set f [socket localhost 9999]
    % fconfigure $f -buffering line
    % puts $f rrr
    % gets $f
    % close $f w
    % gets $f
    can not find channel named "sock3"

    and at the syscall level, the fd is close()d too, as shown by starce:

    Process 14165 attached - interrupt to quit
    read(0, "close $f w\n", 4096) = 11
    close(3) = 0
    write(1, "% ", 2) = 2

  • Attached a new version fixing all the known issues on the socket side:

    (1) The test on flags to detect a true half-close was buggy.
    (this explained the full-close)

    (2) Once we really decide to do the half-close, let's not forget to update the statePtr->flags ;-)
    (this explained why a [close $f w];[close $f r] did not close)

    Now I've just noticed that Pipes don't have a close2proc on unix. Will do that now.

    File Added: halfclosesock-3.patch

  • Attached halfclose-4.patch which now includes a close2proc for pipes in unix too.
    Also tweaked a bit the error message when closing an already-closed half, to better distinguish from the "unsupported by channel type" case.
    Would appreciate help for the tests and doc, busy at work now :-(

    File Added: halfclose-4.patch

  • Thanks for the work Alexandre.

  • half-close-4 + very basic tests, and change in closeex re handling of error bypass.

  • Now that the TIP has been accepted, starting from your halfclose-5.patch, I'll look at the doc & tests, aiming for a single-shot commit.

  • Ok. Thanks.

  • Committed to HEAD this patch augmented by appropriate additions in chan.n and chanio.test.
    There still are two problems to fix quickly:
    (1) A half-close-write on unflushed data crashes. This is because we reset internal fields too quickly, and the flushing occurs with a NULL client data pointer. The workaround is to flush before [close w]. Used in the test.
    (2) On Windows the half-close test in chanio.test fails with ECONNRESET. So I wrapped it in an if {0}.

  • I've converted the 'if 0's into 'knownBug' constraints. (Can't chase Win problems further at the moment; away from my Win box...)

  • Thanks Donal, nice idiom.
    Please rather followup on this issue in 2444274.