From df162f81b863ae6ae81d4550033b9c0c5ee280f2 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 25 May 2004 22:22:58 +0000 Subject: Prototype fix for [Bug 960410] that tries to move hash table cleanup somewhere more reliable. --- ChangeLog | 6 ++++++ generic/tclInterp.c | 21 ++++++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5f07ecd..93bfc3d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-05-25 Donal K. Fellows + + * generic/tclInterp.c (DeleteScriptLimitCallback): Move all + deletion of script callback hash table entries to happen here so + the entries are correctly removed at the right time. [Bug 960410] + 2004-05-25 Miguel Sofer * docs/global.n: added details for qualified variable names diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 4c673a0..d2d2cea 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.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: tclInterp.c,v 1.33 2004/05/24 21:48:32 dkf Exp $ + * RCS: @(#) $Id: tclInterp.c,v 1.34 2004/05/25 22:23:01 dkf Exp $ */ #include "tclInt.h" @@ -149,13 +149,14 @@ typedef struct InterpInfo { * Limit callbacks handled by scripts are modelled as structures which * are stored in hashes indexed by a two-word key. Note that the type * of the 'type' field in the key is not int; this is to make sure - * that things work properly on 64-bit architectures. + * that things are likely to work properly on 64-bit architectures. */ struct ScriptLimitCallback { Tcl_Interp *interp; Tcl_Obj *scriptObj; int type; + Tcl_HashEntry *entryPtr; }; struct ScriptLimitCallbackKey { @@ -3055,6 +3056,7 @@ DeleteScriptLimitCallback(clientData) (struct ScriptLimitCallback *) clientData; Tcl_DecrRefCount(limitCBPtr->scriptObj); + Tcl_DeleteHashEntry(limitCBPtr->entryPtr); ckfree((char *) limitCBPtr); } @@ -3112,24 +3114,25 @@ SetLimitCallback(interp, type, targetInterp, scriptObj) if (hashPtr != NULL) { Tcl_LimitRemoveHandler(targetInterp, type, CallScriptLimitCallback, Tcl_GetHashValue(hashPtr)); - Tcl_DeleteHashEntry(hashPtr); } return; } + hashPtr = Tcl_CreateHashEntry(&iPtr->limit.callbacks, (char *) &key, + &isNew); + if (!isNew) { + Tcl_LimitRemoveHandler(targetInterp, type, CallScriptLimitCallback, + Tcl_GetHashValue(hashPtr)); + } + limitCBPtr = (struct ScriptLimitCallback *) ckalloc(sizeof(struct ScriptLimitCallback)); limitCBPtr->interp = interp; limitCBPtr->scriptObj = scriptObj; + limitCBPtr->entryPtr = hashPtr; limitCBPtr->type = type; Tcl_IncrRefCount(scriptObj); - hashPtr = Tcl_CreateHashEntry(&iPtr->limit.callbacks, (char *) &key, - &isNew); - if (!isNew) { - Tcl_LimitRemoveHandler(targetInterp, type, CallScriptLimitCallback, - Tcl_GetHashValue(hashPtr)); - } Tcl_LimitAddHandler(targetInterp, type, CallScriptLimitCallback, (ClientData) limitCBPtr, DeleteScriptLimitCallback); Tcl_SetHashValue(hashPtr, (ClientData) limitCBPtr); -- cgit v0.12