summaryrefslogtreecommitdiffstats
path: root/generic/tclIO.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-05-02 15:58:03 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-05-02 15:58:03 (GMT)
commit3f767c15a3a870d5692ae43cd6151fb86ffa2bf3 (patch)
tree9de398663005e19753c1e34cf54b9ad5b0e3c868 /generic/tclIO.c
parentb40083e57b3756f499252aa8a3a0ac428ef7a258 (diff)
parentc72145346d53621e954b69597ccfaebc1cc4e7ba (diff)
downloadtcl-3f767c15a3a870d5692ae43cd6151fb86ffa2bf3.zip
tcl-3f767c15a3a870d5692ae43cd6151fb86ffa2bf3.tar.gz
tcl-3f767c15a3a870d5692ae43cd6151fb86ffa2bf3.tar.bz2
merge trunk
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r--generic/tclIO.c56
1 files changed, 42 insertions, 14 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 0a81a53..d5d4086 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -1748,6 +1748,10 @@ Tcl_StackChannel(
statePtr->csPtrR = NULL;
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;
@@ -1877,6 +1881,13 @@ Tcl_UnstackChannel(
* into the old 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;
/*
@@ -1981,7 +1992,7 @@ Tcl_UnstackChannel(
*/
Tcl_EventuallyFree(chanPtr, TCL_DYNAMIC);
- UpdateInterest(downChanPtr);
+ UpdateInterest(statePtr->topChanPtr);
if (result != 0) {
Tcl_SetErrno(result);
@@ -4546,9 +4557,12 @@ Tcl_GetsObj(
* Regenerate the top channel, in case it was changed due to
* self-modifying reflected transforms.
*/
- /*
- chanPtr = statePtr->topChanPtr;
- */
+
+ if (chanPtr != statePtr->topChanPtr) {
+ Tcl_Release(chanPtr);
+ chanPtr = statePtr->topChanPtr;
+ Tcl_Preserve(chanPtr);
+ }
bufPtr = gs.bufPtr;
if (bufPtr == NULL) {
@@ -4582,9 +4596,11 @@ Tcl_GetsObj(
* Regenerate the top channel, in case it was changed due to
* self-modifying reflected transforms.
*/
- /*
- chanPtr = statePtr->topChanPtr;
- */
+ if (chanPtr != statePtr->topChanPtr) {
+ Tcl_Release(chanPtr);
+ chanPtr = statePtr->topChanPtr;
+ Tcl_Preserve(chanPtr);
+ }
bufPtr = statePtr->inQueueHead;
if (bufPtr != NULL) {
bufPtr->nextRemoved = oldRemoved;
@@ -4624,9 +4640,11 @@ Tcl_GetsObj(
* Regenerate the top channel, in case it was changed due to
* self-modifying reflected transforms.
*/
- /*
- chanPtr = statePtr->topChanPtr;
- */
+ if (chanPtr != statePtr->topChanPtr) {
+ Tcl_Release(chanPtr);
+ chanPtr = statePtr->topChanPtr;
+ Tcl_Preserve(chanPtr);
+ }
UpdateInterest(chanPtr);
Tcl_Release(chanPtr);
return copiedTotal;
@@ -5596,6 +5614,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;
@@ -5621,9 +5644,11 @@ DoReadChars(
* Regenerate the top channel, in case it was changed due to
* self-modifying reflected transforms.
*/
- /*
- chanPtr = statePtr->topChanPtr;
- */
+ if (chanPtr != statePtr->topChanPtr) {
+ Tcl_Release(chanPtr);
+ chanPtr = statePtr->topChanPtr;
+ Tcl_Preserve(chanPtr);
+ }
UpdateInterest(chanPtr);
Tcl_Release(chanPtr);
return copied;
@@ -9510,12 +9535,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) {