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
- assignee changed to: "nobody"
- closer changed to: "nobody"
- cmimetype changed to: "text/x-fossil-wiki"
- 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; }
- foundin changed to: "8.5.15"
- is_private changed to: "0"
- login: "oehhar"
- priority changed to: "5 Medium"
- private_contact changed to: "0f366eb3e9e2fcab52b8ebacd197db9047186a5f"
- resolution changed to: "None"
- severity changed to: "Minor"
- status changed to: "Open"
- submitter changed to: "oehhar"
- subsystem changed to: "24. Channel Commands"
- title changed to:
close returns empty error message if failed non-blocking write flush pending
- type changed to: "Bug"