diff options
Diffstat (limited to 'contrib/tcl/generic/tclFHandle.c')
-rw-r--r-- | contrib/tcl/generic/tclFHandle.c | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/contrib/tcl/generic/tclFHandle.c b/contrib/tcl/generic/tclFHandle.c index 19875c5..f8b3798 100644 --- a/contrib/tcl/generic/tclFHandle.c +++ b/contrib/tcl/generic/tclFHandle.c @@ -8,10 +8,11 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * SCCS: @(#) tclFHandle.c 1.6 96/02/13 16:29:55 + * SCCS: @(#) tclFHandle.c 1.8 96/06/27 15:31:34 */ #include "tcl.h" +#include "tclInt.h" #include "tclPort.h" /* @@ -112,7 +113,7 @@ Tcl_FreeFile(handle) { Tcl_HashEntry *entryPtr; FileHandle *handlePtr = (FileHandle *) handle; - + /* * Invoke free procedure, then delete the handle. */ @@ -121,11 +122,24 @@ Tcl_FreeFile(handle) (*handlePtr->proc)(handlePtr->data); } - entryPtr = Tcl_FindHashEntry(&fileTable, (char *) &handlePtr->key); - if (entryPtr) { - Tcl_DeleteHashEntry(entryPtr); - ckfree((char *) handlePtr); + /* + * Tcl_File structures may be freed as a result of running the + * channel table exit handler. The file table is freed by the file + * table exit handler, which may run before the channel table exit + * handler. The file table exit handler sets the "initialized" + * variable back to zero, so that the Tcl_FreeFile (when invoked + * from the channel table exit handler) can notice that the file + * table has already been destroyed. Otherwise, accessing a + * deleted hash table would cause a panic. + */ + + if (initialized) { + entryPtr = Tcl_FindHashEntry(&fileTable, (char *) &handlePtr->key); + if (entryPtr) { + Tcl_DeleteHashEntry(entryPtr); + } } + ckfree((char *) handlePtr); } /* @@ -240,15 +254,6 @@ static void FileExitProc(clientData) ClientData clientData; /* Not used. */ { - Tcl_HashSearch search; - Tcl_HashEntry *entryPtr; - - entryPtr = Tcl_FirstHashEntry(&fileTable, &search); - - while (entryPtr) { - ckfree(Tcl_GetHashValue(entryPtr)); - entryPtr = Tcl_NextHashEntry(&search); - } - Tcl_DeleteHashTable(&fileTable); + initialized = 0; } |