diff options
author | ferrieux <ferrieux@users.sourceforge.net> | 2012-04-30 21:15:53 (GMT) |
---|---|---|
committer | ferrieux <ferrieux@users.sourceforge.net> | 2012-04-30 21:15:53 (GMT) |
commit | eb6dd9387d7673385d60a6dbf6c24b4f1123706c (patch) | |
tree | d40ef0ee7e8600c7b454feafc52b40112f045943 | |
parent | ccc7189d02db07692cedcc82141038304536e5f5 (diff) | |
download | tcl-eb6dd9387d7673385d60a6dbf6c24b4f1123706c.zip tcl-eb6dd9387d7673385d60a6dbf6c24b4f1123706c.tar.gz tcl-eb6dd9387d7673385d60a6dbf6c24b4f1123706c.tar.bz2 |
Explore enforcing the (implied) law that EAGAIN is forbidden for a blocking channel. Violation discovered is iocmd.tf-24.1[56] after TIP#398. Turns deadlock of these tests into frank failures.
-rw-r--r-- | generic/tclIO.c | 27 | ||||
-rw-r--r-- | tests/ioCmd.test | 3 |
2 files changed, 27 insertions, 3 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index b06c14d..0f2aa28 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2453,13 +2453,35 @@ FlushChannel( */ if ((errorCode == EWOULDBLOCK) || (errorCode == EAGAIN)) { - /* - * This used to check for CHANNEL_NONBLOCKING, and panic if + + + /* PREVIOUS RATIONALE -- UNDER EVALUATION + * + * This used to check for CHANNEL_NONBLOCKING, and panic if * the channel was blocking. However, it appears that setting * stdin to -blocking 0 has some effect on the stdout when * it's a tty channel (dup'ed underneath) */ + /* NEW RATIONALE -- UNDER EVALUATION + * + * We explicitly disallow EAGAIN/EWOULDBLOCK for blocking + * channels, but throw an error instead of panicking, since + * this may be a simple scripting error in a refelected + * channel. + */ + + if (!GotFlag(statePtr, CHANNEL_NONBLOCKING)) { + //Tcl_Panic("EAGAIN Illegally thrown by blocking channel"); + + Tcl_SetChannelError((Tcl_Channel) chanPtr, + Tcl_ObjPrintf("{EAGAIN Illegally thrown by blocking channel \"%s\"}", + Tcl_GetChannelName((Tcl_Channel)chanPtr))); + errorCode=EINVAL; + DiscardOutputQueued(statePtr); + goto done; + } + if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { SetFlag(statePtr, BG_FLUSH_SCHEDULED); UpdateInterest(chanPtr); @@ -2524,7 +2546,6 @@ FlushChannel( * When we get an error we throw away all the output currently * queued. */ - DiscardOutputQueued(statePtr); continue; } else { diff --git a/tests/ioCmd.test b/tests/ioCmd.test index 4c08229..6b1da73 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -2575,6 +2575,7 @@ test iocmd.tf-24.15 {chan write, EAGAIN means that writing is not allowed at thi set res } -cleanup { proc foo {args} {onfinal; set ::done-24.15 1; return 3} + after 1000 {set ::done-24.15 2} vwait done-24.15 rename foo {} unset res @@ -2603,10 +2604,12 @@ test iocmd.tf-24.16 {chan write, note the background flush setup by close due to proc foo {args} { onfinal; note BG ; track ; set ::endbody-24.16 1} # Flush (sic!) the event-queue to capture the write from a # BG-flush. + after 1000 {set ::endbody-24.16 2} vwait endbody-24.16 set res } -cleanup { proc foo {args} {onfinal; set ::done-24.16 1; return 3} + after 1000 {set ::done-24.16 2} vwait done-24.16 rename foo {} unset res |