diff options
author | dgp <dgp@users.sourceforge.net> | 2014-02-06 22:48:34 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2014-02-06 22:48:34 (GMT) |
commit | 5c88f32139644538542058b07833e3731af7be18 (patch) | |
tree | aeb499092f019306364aa6075eab104c484306f5 /generic/tclBasic.c | |
parent | 1d139334be18bced5b3d4d6b1117e47696032f07 (diff) | |
parent | 32a6fce0618ed21d85cf47b4b842ea9ee2c0c2e6 (diff) | |
download | tcl-5c88f32139644538542058b07833e3731af7be18.zip tcl-5c88f32139644538542058b07833e3731af7be18.tar.gz tcl-5c88f32139644538542058b07833e3731af7be18.tar.bz2 |
[a4494e28ed] Use flag bit instead of NULL pointer to suppress
teardown list of imported commands when the original command
gets re-created. This prevents the panic otherwise possible when
the invalid state represented by the NULL pointer is encountered
during a command delete trace.
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r-- | generic/tclBasic.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 46b532b..2a334c4 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -2085,10 +2085,19 @@ Tcl_CreateCommand( */ cmdPtr = Tcl_GetHashValue(hPtr); - oldRefPtr = cmdPtr->importRefPtr; - cmdPtr->importRefPtr = NULL; + cmdPtr->refCount++; + if (cmdPtr->importRefPtr) { + cmdPtr->flags |= CMD_REDEF_IN_PROGRESS; + } Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr); + + if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) { + oldRefPtr = cmdPtr->importRefPtr; + cmdPtr->importRefPtr = NULL; + } + TclCleanupCommandMacro(cmdPtr); + hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew); if (!isNew) { /* @@ -2272,10 +2281,19 @@ Tcl_CreateObjCommand( * intact. */ - oldRefPtr = cmdPtr->importRefPtr; - cmdPtr->importRefPtr = NULL; + cmdPtr->refCount++; + if (cmdPtr->importRefPtr) { + cmdPtr->flags |= CMD_REDEF_IN_PROGRESS; + } Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr); + + if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) { + oldRefPtr = cmdPtr->importRefPtr; + cmdPtr->importRefPtr = NULL; + } + TclCleanupCommandMacro(cmdPtr); + hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew); if (!isNew) { /* @@ -3117,12 +3135,13 @@ Tcl_DeleteCommandFromToken( * commands were created that refer back to this command. Delete these * imported commands now. */ - - for (refPtr = cmdPtr->importRefPtr; refPtr != NULL; - refPtr = nextRefPtr) { - nextRefPtr = refPtr->nextPtr; - importCmd = (Tcl_Command) refPtr->importedCmdPtr; - Tcl_DeleteCommandFromToken(interp, importCmd); + if (!(cmdPtr->flags & CMD_REDEF_IN_PROGRESS)) { + for (refPtr = cmdPtr->importRefPtr; refPtr != NULL; + refPtr = nextRefPtr) { + nextRefPtr = refPtr->nextPtr; + importCmd = (Tcl_Command) refPtr->importedCmdPtr; + Tcl_DeleteCommandFromToken(interp, importCmd); + } } /* |