summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2004-05-25 22:22:58 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2004-05-25 22:22:58 (GMT)
commitdf162f81b863ae6ae81d4550033b9c0c5ee280f2 (patch)
tree8a5e020a0498c6e7182c39806f20ea6d6ae51fa9
parentc85709f537091cdf9538cbeed4d4036d0247dc94 (diff)
downloadtcl-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--ChangeLog6
-rw-r--r--generic/tclInterp.c21
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 <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);