diff options
author | dgp <dgp@users.sourceforge.net> | 2014-11-05 20:34:03 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2014-11-05 20:34:03 (GMT) |
commit | 836a10622561a68136fe41a106892b55aafb9fc3 (patch) | |
tree | e1516420790845e1f6c6fb4a4a7682c3c428214e | |
parent | db0b450fcc8673487056f6292838cc14ffa54c5e (diff) | |
download | tcl-836a10622561a68136fe41a106892b55aafb9fc3.zip tcl-836a10622561a68136fe41a106892b55aafb9fc3.tar.gz tcl-836a10622561a68136fe41a106892b55aafb9fc3.tar.bz2 |
Reflected Transform channel fix. Be sure each EOF on the base channel gets
passed up to become an eof of the transform before continuing on to additional
ReadRaw() from the base channel. This way we don't miss fleeting EOFs.
-rw-r--r-- | generic/tclIORTrans.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index 8f3ef3c..8baa9ad 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -161,6 +161,7 @@ typedef struct { int mode; /* Mask of R/W mode */ int nonblocking; /* Flag: Channel is blocking or not. */ int readIsDrained; /* Flag: Read buffers are flushed. */ + int eofPending; /* Flag: EOF seen down, but not raised up */ int dead; /* Boolean signal that some operations * should no longer be attempted. */ ResultBuffer result; @@ -1082,6 +1083,10 @@ ReflectInput( bufObj = Tcl_NewByteArrayObj(NULL, toRead); Tcl_IncrRefCount(bufObj); gotBytes = 0; + if (rtPtr->eofPending) { + goto stop; + } + rtPtr->readIsDrained = 0; while (toRead > 0) { /* * Loop until the request is satisfied (or no data available from @@ -1097,9 +1102,9 @@ ReflectInput( goto stop; } - if (rtPtr->readIsDrained) { - goto stop; - } + if (rtPtr->eofPending) { + goto stop; + } /* @@ -1170,6 +1175,8 @@ ReflectInput( * Zero returned from Tcl_ReadRaw() always indicates EOF * on the down channel. */ + + rtPtr->eofPending = 1; /* * Now this is a bit different. The partial data waiting is @@ -1212,6 +1219,9 @@ ReflectInput( } /* while toRead > 0 */ stop: + if (gotBytes == 0) { + rtPtr->eofPending = 0; + } Tcl_DecrRefCount(bufObj); Tcl_Release(rtPtr); return gotBytes; @@ -1767,6 +1777,7 @@ NewReflectedTransform( rtPtr->timer = NULL; rtPtr->mode = 0; rtPtr->readIsDrained = 0; + rtPtr->eofPending = 0; rtPtr->nonblocking = (((Channel *) parentChan)->state->flags & CHANNEL_NONBLOCKING); rtPtr->dead = 0; @@ -3319,6 +3330,7 @@ TransformClear( (void) InvokeTclMethod(rtPtr, "clear", NULL, NULL, NULL); rtPtr->readIsDrained = 0; + rtPtr->eofPending = 0; ResultClear(&rtPtr->result); } |