diff options
author | dgp <dgp@users.sourceforge.net> | 2014-05-02 15:41:45 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2014-05-02 15:41:45 (GMT) |
commit | 5bcf70eb927f88300b80922ab2d2e0c5b9f0985b (patch) | |
tree | 04ac1ca9ee44bcb9eb11fd2168ef6d5c7746d59e /generic/tclIO.c | |
parent | ab0e4b9897d95d1c3f643524a08c99425055ea5e (diff) | |
parent | 7404b09c618ba2e4af7bb1cd0f043d50eff6f484 (diff) | |
download | tcl-5bcf70eb927f88300b80922ab2d2e0c5b9f0985b.zip tcl-5bcf70eb927f88300b80922ab2d2e0c5b9f0985b.tar.gz tcl-5bcf70eb927f88300b80922ab2d2e0c5b9f0985b.tar.bz2 |
merge 8.5
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r-- | generic/tclIO.c | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index f4c8255..44db3f2 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1654,6 +1654,10 @@ Tcl_StackChannel( csPtrW = statePtr->csPtrW; statePtr->csPtrW = NULL; + /* + * TODO: Examine what can go wrong if Tcl_Flush() call disturbs + * the stacking state of this channel during its operations. + */ if (Tcl_Flush((Tcl_Channel) prevChanPtr) != TCL_OK) { statePtr->csPtrR = csPtrR; statePtr->csPtrW = csPtrW; @@ -1786,6 +1790,13 @@ Tcl_UnstackChannel( * structure. */ + /* + * TODO: Figure out how to handle the situation where the chan + * operations called below by this unstacking operation cause + * another unstacking recursively. In that case the downChanPtr + * value we're holding on to will not be the right thing. + */ + Channel *downChanPtr = chanPtr->downChanPtr; /* @@ -1906,7 +1917,7 @@ Tcl_UnstackChannel( */ Tcl_EventuallyFree(chanPtr, TCL_DYNAMIC); - UpdateInterest(downChanPtr); + UpdateInterest(statePtr->topChanPtr); if (result != 0) { Tcl_SetErrno(result); @@ -4132,6 +4143,17 @@ Tcl_GetsObj( */ gotEOL: + /* + * Regenerate the top channel, in case it was changed due to + * self-modifying reflected transforms. + */ + + if (chanPtr != statePtr->topChanPtr) { + Tcl_Release(chanPtr); + chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); + } + bufPtr = gs.bufPtr; if (bufPtr == NULL) { Tcl_Panic("Tcl_GetsObj: gotEOL reached with bufPtr==NULL"); @@ -4160,6 +4182,15 @@ Tcl_GetsObj( */ restore: + /* + * Regenerate the top channel, in case it was changed due to + * self-modifying reflected transforms. + */ + if (chanPtr != statePtr->topChanPtr) { + Tcl_Release(chanPtr); + chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); + } bufPtr = statePtr->inQueueHead; if (bufPtr != NULL) { bufPtr->nextRemoved = oldRemoved; @@ -4195,6 +4226,15 @@ Tcl_GetsObj( */ done: + /* + * Regenerate the top channel, in case it was changed due to + * self-modifying reflected transforms. + */ + if (chanPtr != statePtr->topChanPtr) { + Tcl_Release(chanPtr); + chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); + } UpdateInterest(chanPtr); Tcl_Release(chanPtr); return copiedTotal; @@ -5161,6 +5201,11 @@ DoReadChars( ResetFlag(statePtr, CHANNEL_BLOCKED); } result = GetInput(chanPtr); + if (chanPtr != statePtr->topChanPtr) { + Tcl_Release(chanPtr); + chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); + } if (result != 0) { if (result == EAGAIN) { break; @@ -5182,6 +5227,15 @@ DoReadChars( */ done: + /* + * Regenerate the top channel, in case it was changed due to + * self-modifying reflected transforms. + */ + if (chanPtr != statePtr->topChanPtr) { + Tcl_Release(chanPtr); + chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); + } UpdateInterest(chanPtr); Tcl_Release(chanPtr); return copied; @@ -9077,12 +9131,15 @@ StackSetBlockMode( { int result = 0; Tcl_DriverBlockModeProc *blockModeProc; + ChannelState *statePtr = chanPtr->state; /* * Start at the top of the channel stack + * TODO: Examine what can go wrong when blockModeProc calls + * disturb the stacking state of the channel. */ - chanPtr = chanPtr->state->topChanPtr; + chanPtr = statePtr->topChanPtr; while (chanPtr != NULL) { blockModeProc = Tcl_ChannelBlockModeProc(chanPtr->typePtr); if (blockModeProc != NULL) { |