summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2016-07-07 18:44:56 (GMT)
committerdgp <dgp@users.sourceforge.net>2016-07-07 18:44:56 (GMT)
commitfc2bc121acb78c5544d30d1e7ceb507397fe3e78 (patch)
tree5d309a43748cca3dbc0a6c53fac9dc3f3fa6ffe8
parentf7aa28a9960d172ef84736f3609940c5564d5325 (diff)
downloadtcl-fc2bc121acb78c5544d30d1e7ceb507397fe3e78.zip
tcl-fc2bc121acb78c5544d30d1e7ceb507397fe3e78.tar.gz
tcl-fc2bc121acb78c5544d30d1e7ceb507397fe3e78.tar.bz2
To use a Tcl_Command token [aka (Command *)] for epoch checking, we must not
permit it to be freed while we hold it or else it could be mistaken for another token allocated later that just happens to reside at the same address. (Command *) preservation machinery already exists, just need to use it. An extension facing the same problem might have to rely on command delete traces. Earlier revisions used (Namespace *) lifetime to achieve the same results, but that's really an indirect (possibly non-robust) path to achieving the proper goal. Valgrind is happy now.
-rw-r--r--generic/tclEnsemble.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c
index 5c47ce3..24b6b9a 100644
--- a/generic/tclEnsemble.c
+++ b/generic/tclEnsemble.c
@@ -93,7 +93,7 @@ typedef struct {
int epoch; /* Used to confirm when the data in this
* really structure matches up with the
* ensemble. */
- Tcl_Command token; /* Reference to the comamnd for which this
+ Command *token; /* Reference to the command for which this
* structure is a cache of the resolution. */
Tcl_Obj *fix; /* Corrected spelling, if needed. */
Tcl_HashEntry *hPtr; /* Direct link to entry in the subcommand
@@ -1727,7 +1727,7 @@ NsEnsembleImplementationCmdNR(
EnsembleCmdRep *ensembleCmd = subObj->internalRep.twoPtrValue.ptr1;
if (ensembleCmd->epoch == ensemblePtr->epoch &&
- ensembleCmd->token == ensemblePtr->token) {
+ ensembleCmd->token == (Command *)ensemblePtr->token) {
prefixObj = Tcl_GetHashValue(ensembleCmd->hPtr);
Tcl_IncrRefCount(prefixObj);
if (ensembleCmd->fix) {
@@ -2404,7 +2404,8 @@ MakeCachedEnsembleCommand(
*/
ensembleCmd->epoch = ensemblePtr->epoch;
- ensembleCmd->token = ensemblePtr->token;
+ ensembleCmd->token = (Command *) ensemblePtr->token;
+ ensembleCmd->token->refCount++;
if (fix) {
Tcl_IncrRefCount(fix);
}
@@ -2790,6 +2791,7 @@ FreeEnsembleCmdRep(
{
EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
+ TclCleanupCommandMacro(ensembleCmd->token);
if (ensembleCmd->fix) {
Tcl_DecrRefCount(ensembleCmd->fix);
}
@@ -2827,6 +2829,7 @@ DupEnsembleCmdRep(
copyPtr->internalRep.twoPtrValue.ptr1 = ensembleCopy;
ensembleCopy->epoch = ensembleCmd->epoch;
ensembleCopy->token = ensembleCmd->token;
+ ensembleCopy->token->refCount++;
ensembleCopy->fix = ensembleCmd->fix;
if (ensembleCopy->fix) {
Tcl_IncrRefCount(ensembleCopy->fix);