diff options
author | dgp <dgp@users.sourceforge.net> | 2016-07-07 18:44:56 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2016-07-07 18:44:56 (GMT) |
commit | fc2bc121acb78c5544d30d1e7ceb507397fe3e78 (patch) | |
tree | 5d309a43748cca3dbc0a6c53fac9dc3f3fa6ffe8 /generic/tclEnsemble.c | |
parent | f7aa28a9960d172ef84736f3609940c5564d5325 (diff) | |
download | tcl-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.
Diffstat (limited to 'generic/tclEnsemble.c')
-rw-r--r-- | generic/tclEnsemble.c | 9 |
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); |