From 9c026cec4e9775bcdcc7009b9866e4e570ba8b6e Mon Sep 17 00:00:00 2001 From: andreas_kupries Date: Thu, 22 Jan 2009 00:05:13 +0000 Subject: * generic/tclIORChan.c (ReflectClose): Fix for [Bug 2458202]. Closing a channel may supply NULL for the 'interp'. Test for finalization needs to be different, and one place has to pull the interp out of the channel instead. --- ChangeLog | 7 +++++++ generic/tclIORChan.c | 21 +++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 10edf6a..894f5f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-01-21 Andreas Kupries + + * generic/tclIORChan.c (ReflectClose): Fix for [Bug 2458202]. + Closing a channel may supply NULL for the 'interp'. Test for + finalization needs to be different, and one place has to pull the + interp out of the channel instead. + 2009-01-19 Kevin B. Kenny * unix/Makefile.in: Added a CONFIG_INSTALL_DIR parameter so that diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index d13b9aac..c9a294b 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -15,7 +15,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclIORChan.c,v 1.28.2.5 2008/07/03 17:38:18 andreas_kupries Exp $ + * RCS: @(#) $Id: tclIORChan.c,v 1.28.2.6 2009/01/22 00:05:14 andreas_kupries Exp $ */ #include @@ -1046,7 +1046,7 @@ ReflectClose( ReflectedChannelMap* rcmPtr; /* Map of reflected channels with handlers in this interp */ Tcl_HashEntry* hPtr; /* Entry in the above map */ - if (interp == NULL) { + if (TclInThreadExit()) { /* * This call comes from TclFinalizeIOSystem. There are no * interpreters, and therefore we cannot call upon the handler command @@ -1134,13 +1134,18 @@ ReflectClose( * NOTE: The channel may not be in the map. This is ok, that happens * when the channel was created in a different interpreter and/or * thread and then was moved here. + * + * NOTE: The channel may have been removed from the map already via + * the per-interp DeleteReflectedChannelMap exit-handler. */ - - rcmPtr = GetReflectedChannelMap (interp); - hPtr = Tcl_FindHashEntry (&rcmPtr->map, - Tcl_GetChannelName (rcPtr->chan)); - if (hPtr) { - Tcl_DeleteHashEntry (hPtr); + + if (rcPtr->interp) { + rcmPtr = GetReflectedChannelMap (rcPtr->interp); + hPtr = Tcl_FindHashEntry (&rcmPtr->map, + Tcl_GetChannelName (rcPtr->chan)); + if (hPtr) { + Tcl_DeleteHashEntry (hPtr); + } } #ifdef TCL_THREADS rcmPtr = GetThreadReflectedChannelMap(); -- cgit v0.12