diff options
author | dgp <dgp@users.sourceforge.net> | 2011-09-20 17:33:59 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2011-09-20 17:33:59 (GMT) |
commit | 4e2761163f1ad08f5ef986c9848cacd0be15088c (patch) | |
tree | 85cfa820c0fd70e83e4167238e54fc8de7b71aed | |
parent | 26d9f7564cf5104695a2ed6e6c418d358b436776 (diff) | |
download | tcl-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.c | 19 |
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. |