summaryrefslogtreecommitdiffstats
path: root/generic/tclIO.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2011-08-19 16:05:46 (GMT)
committerdgp <dgp@users.sourceforge.net>2011-08-19 16:05:46 (GMT)
commitf92360fdcc3f4a6a956097e1f5b41a5bd81d6ebe (patch)
treeaadf727ff63679c8cdbf82f2eeb93c772e25f236 /generic/tclIO.c
parent31839bbef437a8f7f384a8bf9530812e5513c066 (diff)
downloadtcl-f92360fdcc3f4a6a956097e1f5b41a5bd81d6ebe.zip
tcl-f92360fdcc3f4a6a956097e1f5b41a5bd81d6ebe.tar.gz
tcl-f92360fdcc3f4a6a956097e1f5b41a5bd81d6ebe.tar.bz2
Preserve the chanPtr during FlushChannel so that channel drivers
don't yank it away before we're done with it.
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r--generic/tclIO.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 95afd63..946b53a 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -2356,6 +2356,7 @@ FlushChannel(
* of the queued output to the channel.
*/
+ Tcl_Preserve(chanPtr);
while (1) {
/*
* If the queue is empty and there is a ready current buffer, OR if
@@ -2385,7 +2386,8 @@ FlushChannel(
*/
if (!calledFromAsyncFlush && GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
- return 0;
+ errorCode = 0;
+ goto done;
}
/*
@@ -2532,7 +2534,7 @@ FlushChannel(
if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
if (wroteSome) {
- return errorCode;
+ goto done;
} else if (statePtr->outQueueHead == NULL) {
ResetFlag(statePtr, BG_FLUSH_SCHEDULED);
ChanWatch(chanPtr, statePtr->interestMask);
@@ -2549,7 +2551,8 @@ FlushChannel(
(statePtr->outQueueHead == NULL) &&
((statePtr->curOutPtr == NULL) ||
IsBufferEmpty(statePtr->curOutPtr))) {
- return CloseChannel(interp, chanPtr, errorCode);
+ errorCode = CloseChannel(interp, chanPtr, errorCode);
+ goto done;
}
/*
@@ -2562,8 +2565,12 @@ FlushChannel(
(statePtr->outQueueHead == NULL) &&
((statePtr->curOutPtr == NULL) ||
IsBufferEmpty(statePtr->curOutPtr))) {
- return CloseChannelPart(interp, chanPtr, errorCode, TCL_CLOSE_WRITE);
+ errorCode = CloseChannelPart(interp, chanPtr, errorCode, TCL_CLOSE_WRITE);
+ goto done;
}
+
+ done:
+ Tcl_Release(chanPtr);
return errorCode;
}