Tcl Source Code

Ticket Change Details
Login
Overview

Artifact ID: b11588af583c7a8fd202bc940cbbc000f7301d3a
Ticket: 97069ea11aca3783949c0379725eed90f5573c23
close returns empty error message if failed non-blocking write flush pending
User & Date: oehhar 2014-03-25 08:50:53
Changes

  1. assignee changed to: "nobody"
  2. closer changed to: "nobody"
  3. cmimetype changed to: "text/x-fossil-wiki"
  4. comment changed to:
    <h1>Issue</h1>
    The trailing close in the following sequence throws an error but no error message:
    <verbatim>
    % set sock [socket -async localhost 30001]
    sock420
    % fconfigure $sock -blocking 0
    % puts $sock ok
    % flush $sock
    % fileevent $sock writable {set x 1}
    % vwait x
    % catch {close $sock} e d
    1
    % set e
    % set d
    -code 1 -level 0 -errorstack {INNER {invokeStk1 close sock420}} -errorcode NONE
    -errorinfo {
        while executing
    "close $sock"} -errorline 1
    </verbatim>
    
    This arises on the following platforms:
       *   TCL 8.5.15 on Windows Vista 32 bit 
       *   TCL 8.6.1 on Windows Vista 32 bit
       *   TCL 8.6.1 on Linux too (Reported bei Reinhard Max)
    
    <h1>Possible reasons</h1>
    
    The error is generated by a backround flush sheduled by the writable event.
    The error code is stored in unreportedError.
    Eventually, the error message is missing in unreportedMsg.
    
    A debug trace on tclIO.c:
    
    <h2>flush $sock</h2>
       *   tclIO.c:FlushChannel()
       *   calls tclWinSock.c:TclOutputProc("ok"), which returns error EWOULDBLOCK
       *   Sets flag BG_FLUSH_SCHEDULED
       *   Clears error
    
    <h2>vwait x</h2>
       *   tclIO.c:FlushChannel(calledFromAsyncFlush=1)
       *   calls tclWinSock.c:TclOutputProc("ok"), which tries to write and returns error 126
       *   Sets statePtr->unreportedError = errorCode (126)
       *   statePtr->unreportedMsg = msg (NULL)
       *   Calls DiscardOutputQueued(statePtr)
       *   Flag BG_FLUSH_SCHEDULED is cleared (no data)
    
    <h2>close $sock</h2>
       *   tclIO.c:Tcl_Close()
       *   > flushcode = FlushChannel(interp, chanPtr, 0); -> flushcode = 126
       *   >> errorCode = CloseChannel(interp, chanPtr, errorCode); -> errorCode = 126
       *   >>> result = ChanClose(chanPtr, interp); -> result = 0
       *   >>>> tclWinSock.c:TclCloseProc(), which succeeds
       *   >>> errorCode = statePtr->unreportedError; (126)
       *   >>> Tcl_SetChannelErrorInterp(interp, statePtr->unreportedMsg); (no action, unreportedMsg = NULL)
       *   >>> CloseChannel: return errorCode (126)
       *   >> FLushChannel: return errorCode (126)
       *   > if ((flushcode != 0) || (result != 0)) { return TCL_ERROR; }
    
  5. foundin changed to: "8.5.15"
  6. is_private changed to: "0"
  7. login: "oehhar"
  8. priority changed to: "5 Medium"
  9. private_contact changed to: "0f366eb3e9e2fcab52b8ebacd197db9047186a5f"
  10. resolution changed to: "None"
  11. severity changed to: "Minor"
  12. status changed to: "Open"
  13. submitter changed to: "oehhar"
  14. subsystem changed to: "24. Channel Commands"
  15. title changed to:
    close returns empty error message if failed non-blocking write flush pending
    
  16. type changed to: "Bug"