summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2011-09-20 17:33:59 (GMT)
committerdgp <dgp@users.sourceforge.net>2011-09-20 17:33:59 (GMT)
commit4e2761163f1ad08f5ef986c9848cacd0be15088c (patch)
tree85cfa820c0fd70e83e4167238e54fc8de7b71aed
parent26d9f7564cf5104695a2ed6e6c418d358b436776 (diff)
downloadtcl-4e2761163f1ad08f5ef986c9848cacd0be15088c.zip
tcl-4e2761163f1ad08f5ef986c9848cacd0be15088c.tar.gz
tcl-4e2761163f1ad08f5ef986c9848cacd0be15088c.tar.bz2
Re-using the "interp" field to signal a dead channel (via NULL value)
interfered with conditional cleanup tasks testing for "the right interp" Added a new field "dead" to perform the dead channel signalling task so the corrupted logic is avoided.
-rw-r--r--generic/tclIORChan.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c
index 61c8475..49e2930 100644
--- a/generic/tclIORChan.c
+++ b/generic/tclIORChan.c
@@ -121,6 +121,9 @@ typedef struct {
int interest; /* Mask of events the channel is interested
* in. */
+ int dead; /* Boolean signal that some operations
+ * should no longer be attempted. */
+
/*
* Note regarding the usage of timers.
*
@@ -1128,7 +1131,7 @@ ReflectClose(
* the per-interp DeleteReflectedChannelMap exit-handler.
*/
- if (rcPtr->interp) {
+ if (!rcPtr->dead) {
rcmPtr = GetReflectedChannelMap(rcPtr->interp);
hPtr = Tcl_FindHashEntry(&rcmPtr->map,
Tcl_GetChannelName(rcPtr->chan));
@@ -2022,6 +2025,7 @@ NewReflectedChannel(
rcPtr->chan = NULL;
rcPtr->methods = 0;
rcPtr->interp = interp;
+ rcPtr->dead = 0;
#ifdef TCL_THREADS
rcPtr->thread = Tcl_GetCurrentThread();
#endif
@@ -2155,6 +2159,7 @@ FreeReflectedChannel(
*/
ckfree(chanPtr->typePtr);
+ chanPtr->typePtr = NULL;
}
FreeReflectedChannelArgs(rcPtr);
@@ -2201,7 +2206,7 @@ InvokeTclMethod(
int result; /* Result code of method invokation */
Tcl_Obj *resObj = NULL; /* Result of method invokation. */
- if (!rcPtr->interp) {
+ if (rcPtr->dead) {
/*
* The channel is marked as dead. Bail out immediately, with an
* appropriate error.
@@ -2365,7 +2370,7 @@ ErrnoReturn(
int code;
Tcl_InterpState sr; /* State of handler interp */
- if (!rcPtr->interp) {
+ if (rcPtr->dead) {
return 0;
}
@@ -2474,7 +2479,7 @@ DeleteReflectedChannelMap(
chan = Tcl_GetHashValue(hPtr);
rcPtr = Tcl_GetChannelInstanceData(chan);
- rcPtr->interp = NULL;
+ rcPtr->dead = 1;
Tcl_DeleteHashEntry(hPtr);
}
Tcl_DeleteHashTable(&rcmPtr->map);
@@ -2549,6 +2554,8 @@ DeleteReflectedChannelMap(
continue;
}
+ rcPtr->dead = 1;
+ FreeReflectedChannelArgs(rcPtr);
Tcl_DeleteHashEntry(hPtr);
}
#endif
@@ -2678,7 +2685,7 @@ DeleteThreadReflectedChannelMap(
Tcl_Channel chan = Tcl_GetHashValue(hPtr);
ReflectedChannel *rcPtr = Tcl_GetChannelInstanceData(chan);
- rcPtr->interp = NULL;
+ rcPtr->dead = 1;
FreeReflectedChannelArgs(rcPtr);
Tcl_DeleteHashEntry(hPtr);
}
@@ -2702,7 +2709,7 @@ ForwardOpToOwnerThread(
Tcl_MutexLock(&rcForwardMutex);
- if (rcPtr->interp == NULL) {
+ if (rcPtr->dead) {
/*
* The channel is marked as dead. Bail out immediately, with an
* appropriate error. Do not forget to unlock the mutex on this path.