summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--generic/tclIO.c5
-rw-r--r--tests/ioCmd.test31
3 files changed, 39 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 4126cee..6ebfce0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2011-08-17 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+ * generic/tclIO.c: [Bug 2946474] Consistently resume backgrounded
+ * tests/ioCmd.test: flushes+closes when exiting.
+
+2011-08-17 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+
* doc/interp.n: Document TIP 378's one-way-ness.
2011-08-17 Don Porter <dgp@users.sourceforge.net>
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 78c1dc0..a19fde8 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -414,8 +414,8 @@ TclFinalizeIOSubsystem(void)
statePtr != NULL;
statePtr = statePtr->nextCSPtr) {
chanPtr = statePtr->topChanPtr;
- if (!GotFlag(statePtr, CHANNEL_INCLOSE | CHANNEL_CLOSED |
- CHANNEL_DEAD)) {
+ if (!GotFlag(statePtr, CHANNEL_INCLOSE | CHANNEL_CLOSED | CHANNEL_DEAD)
+ || GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
active = 1;
break;
}
@@ -458,6 +458,7 @@ TclFinalizeIOSubsystem(void)
* The refcount is greater than zero, so flush the channel.
*/
+ ResetFlag(statePtr, BG_FLUSH_SCHEDULED);
Tcl_Flush((Tcl_Channel) chanPtr);
/*
diff --git a/tests/ioCmd.test b/tests/ioCmd.test
index 82f83db..6536072 100644
--- a/tests/ioCmd.test
+++ b/tests/ioCmd.test
@@ -2592,9 +2592,40 @@ test iocmd.tf-24.15 {chan write, EAGAIN means that writing is not allowed at thi
} -cleanup {
rename foo {}
unset res
+ update
} -result {{write rc* ABC} {watch rc* write} {}} \
-constraints {testchannel testthread}
+test iocmd.tf-24.16 {chan write, note the background flush setup by close due to the EAGAIN leaving data in buffers.} -match glob -setup {
+ set res {}
+ proc foo {args} {
+ oninit; onfinal; track
+ # Note: The EAGAIN signals that the channel cannot accept
+ # write requests right now, this in turn causes the IO core to
+ # request the generation of writable events (see expected
+ # result below, and compare to case 24.14 above).
+ error EAGAIN
+ }
+ set c [chan create {r w} foo]
+} -body {
+ notes [inthread $c {
+ note [puts -nonewline $c ABC ; flush $c]
+ close $c
+ notes
+ } c]
+ # Replace handler with all-tracking one which doesn't error.
+ # This will tell us if a write-due-flush is there.
+ proc foo {args} { note BG ; track }
+ # Flush (sic!) the event-queue to capture the write from a
+ # BG-flush.
+ update
+ set res
+} -cleanup {
+ rename foo {}
+ unset res
+} -result {{write rc* ABC} {watch rc* write} {} BG {write rc* ABC}} \
+ -constraints {testchannel testthread}
+
# --- === *** ###########################
# method cgetall