summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhobbs <hobbs>2000-06-02 05:20:09 (GMT)
committerhobbs <hobbs>2000-06-02 05:20:09 (GMT)
commit25eb6f30ba3b8c53a6a7e239c038510abed59937 (patch)
treeed945b2ae00685b8a367868617df44e3eb3b2c52
parentfe38772e8639b48fcfd4b9c98f4527b3cdf8ff5a (diff)
downloadtcl-25eb6f30ba3b8c53a6a7e239c038510abed59937.zip
tcl-25eb6f30ba3b8c53a6a7e239c038510abed59937.tar.gz
tcl-25eb6f30ba3b8c53a6a7e239c038510abed59937.tar.bz2
(CloseChannel): further extended CloseChannel in the stacked case
to effect certain operations on the next channel that would have been done in Tcl_Close. Also added CHANNEL_CLOSED and removed (TCL_READABLE|TCL_WRITABLE) bits from chanPtr->flags. Changed final reset of the WatchProc to check the chanDownPtr's (next) interestMask.
-rw-r--r--ChangeLog6
-rw-r--r--generic/tclIO.c73
2 files changed, 68 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 70cb148..5e48a5e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,12 @@
* generic/tclIO.c (CloseChannel): Rewrote CloseChannel code to
unstack a channel during the close process. Fixed a refcount bug
in Tcl_UnstackChannel. [Bug: 5623]
+ (CloseChannel): further extended CloseChannel in the stacked case
+ to effect certain operations on the next channel that would have
+ been done in Tcl_Close. Also added CHANNEL_CLOSED and removed
+ (TCL_READABLE|TCL_WRITABLE) bits from chanPtr->flags. Changed
+ final reset of the WatchProc to check the chanDownPtr's (next)
+ interestMask.
2000-05-29 Sandeep Tamhankar <sandeep@scriptics.com>
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 66476d2..1766b9a 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIO.c,v 1.20.2.1 2000/06/02 03:01:37 hobbs Exp $
+ * RCS: @(#) $Id: tclIO.c,v 1.20.2.2 2000/06/02 05:20:09 hobbs Exp $
*/
#include "tclInt.h"
@@ -2574,7 +2574,9 @@ CloseChannel(interp, chanPtr, errorCode)
* of (unstack) the underlying channel into the TOP channel structure.
*/
- Channel * chanDownPtr = chanPtr->supercedes;
+ ChannelHandler *chPtr, *chNext; /* Iterate over channel handlers. */
+ NextChannelHandler *nhPtr;
+ Channel *chanDownPtr = chanPtr->supercedes;
/*
* Insert ourselves upon back into the list of open channels,
@@ -2584,6 +2586,52 @@ CloseChannel(interp, chanPtr, errorCode)
tsdPtr->firstChanPtr = chanPtr;
/*
+ * Some initial bits taken from Tcl_Close, to be applied to our
+ * underlying channel.
+ */
+
+ /*
+ * Remove any references to channel handlers for this channel that
+ * may be about to be invoked.
+ */
+
+ for (nhPtr = tsdPtr->nestedHandlerPtr;
+ nhPtr != (NextChannelHandler *) NULL;
+ nhPtr = nhPtr->nestedHandlerPtr) {
+ if (nhPtr->nextHandlerPtr &&
+ (nhPtr->nextHandlerPtr->chanPtr == chanDownPtr)) {
+ nhPtr->nextHandlerPtr = NULL;
+ }
+ }
+
+ /*
+ * Remove all the channel handler records attached to the channel
+ * itself.
+ */
+
+ for (chPtr = chanDownPtr->chPtr; chPtr != NULL; chPtr = chNext) {
+ chNext = chPtr->nextPtr;
+ ckfree((char *) chPtr);
+ }
+ chanDownPtr->chPtr = (ChannelHandler *) NULL;
+
+ /*
+ * Cancel any pending copy operation.
+ */
+
+ StopCopy(chanDownPtr->csPtr);
+
+ /*
+ * Ensure that the last output buffer will be flushed.
+ */
+
+ if ((chanDownPtr->curOutPtr != (ChannelBuffer *) NULL) &&
+ (chanDownPtr->curOutPtr->nextAdded >
+ chanDownPtr->curOutPtr->nextRemoved)) {
+ chanDownPtr->flags |= BUFFER_READY;
+ }
+
+ /*
* Free timer associated with the TOP stacked channel, and
* moving the timer for the NEXT stacked channel to the TOP.
*/
@@ -2599,10 +2647,13 @@ CloseChannel(interp, chanPtr, errorCode)
* Bring the information from the NEXT channel into the TOP
* channel, with some exceptions. This additionally
* cuts the NEXT channel out of the chain and frees it.
+ *
+ * We may want to extract unreportedError as well (hobbs).
*/
chanPtr->channelName = chanDownPtr->channelName;
- chanPtr->flags = chanDownPtr->flags;
+ chanPtr->flags = chanDownPtr->flags | CHANNEL_CLOSED;
+ chanPtr->flags &= (~(TCL_READABLE|TCL_WRITABLE));
Tcl_FreeEncoding(chanDownPtr->encoding);
chanDownPtr->encoding = NULL;
@@ -2629,8 +2680,8 @@ CloseChannel(interp, chanPtr, errorCode)
* that interest with underlying channels or the driver.
*/
- if (chanPtr->interestMask) {
- int interest = chanPtr->interestMask;
+ if (chanDownPtr->interestMask) {
+ int interest = chanDownPtr->interestMask;
chanPtr->interestMask = 0;
(chanPtr->typePtr->watchProc)(chanPtr->instanceData, interest);
@@ -6250,7 +6301,7 @@ Tcl_NotifyChannel(channel, mask)
/* Walk down the stack.
*/
- chanPtr = chanPtr-> supercedes;
+ chanPtr = chanPtr->supercedes;
} else {
/* Stop walking the chain, the whole stack was destroyed!
*/
@@ -7017,7 +7068,7 @@ TclTestChannelCmd(clientData, interp, argc, argv)
Tcl_AppendResult(interp, chanPtr->channelName, (char *) NULL);
return TCL_OK;
}
-
+
if ((cmdName[0] == 'o') && (strncmp(cmdName, "open", len) == 0)) {
hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
if (hTblPtr == (Tcl_HashTable *) NULL) {
@@ -7053,7 +7104,7 @@ TclTestChannelCmd(clientData, interp, argc, argv)
Tcl_AppendResult(interp, buf, (char *) NULL);
return TCL_OK;
}
-
+
if ((cmdName[0] == 'q') &&
(strncmp(cmdName, "queuedcr", len) == 0)) {
if (argc != 3) {
@@ -7067,7 +7118,7 @@ TclTestChannelCmd(clientData, interp, argc, argv)
(char *) NULL);
return TCL_OK;
}
-
+
if ((cmdName[0] == 'r') && (strncmp(cmdName, "readable", len) == 0)) {
hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
if (hTblPtr == (Tcl_HashTable *) NULL) {
@@ -7095,7 +7146,7 @@ TclTestChannelCmd(clientData, interp, argc, argv)
Tcl_AppendResult(interp, buf, (char *) NULL);
return TCL_OK;
}
-
+
if ((cmdName[0] == 't') && (strncmp(cmdName, "type", len) == 0)) {
if (argc != 3) {
Tcl_AppendResult(interp, "channel name required",
@@ -7105,7 +7156,7 @@ TclTestChannelCmd(clientData, interp, argc, argv)
Tcl_AppendResult(interp, chanPtr->typePtr->typeName, (char *) NULL);
return TCL_OK;
}
-
+
if ((cmdName[0] == 'w') && (strncmp(cmdName, "writable", len) == 0)) {
hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
if (hTblPtr == (Tcl_HashTable *) NULL) {