diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2004-05-25 22:22:58 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2004-05-25 22:22:58 (GMT) |
commit | df162f81b863ae6ae81d4550033b9c0c5ee280f2 (patch) | |
tree | 8a5e020a0498c6e7182c39806f20ea6d6ae51fa9 | |
parent | c85709f537091cdf9538cbeed4d4036d0247dc94 (diff) | |
download | tcl-df162f81b863ae6ae81d4550033b9c0c5ee280f2.zip tcl-df162f81b863ae6ae81d4550033b9c0c5ee280f2.tar.gz tcl-df162f81b863ae6ae81d4550033b9c0c5ee280f2.tar.bz2 |
Prototype fix for [Bug 960410] that tries to move hash table cleanup somewhere
more reliable.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | generic/tclInterp.c | 21 |
2 files changed, 18 insertions, 9 deletions
@@ -1,3 +1,9 @@ +2004-05-25 Donal K. Fellows <donal.k.fellows@man.ac.uk> + + * 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 <msofer@users.sf.net> * 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); |