diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2010-02-15 11:53:43 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2010-02-15 11:53:43 (GMT) |
commit | a0d1a202239c64ab548f9d515bba530fb475d743 (patch) | |
tree | 58ef89d3285974776896099a22e8bea82da7cef4 /generic/tclNamesp.c | |
parent | 2a083e870cd9bd162468f535c9a9b724516353ea (diff) | |
download | tcl-a0d1a202239c64ab548f9d515bba530fb475d743.zip tcl-a0d1a202239c64ab548f9d515bba530fb475d743.tar.gz tcl-a0d1a202239c64ab548f9d515bba530fb475d743.tar.bz2 |
Fix [Bug 2950259] so that deleting an object by killing its namespace will
reliably call the object's destructor.
Diffstat (limited to 'generic/tclNamesp.c')
-rw-r--r-- | generic/tclNamesp.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index 140c17e..2e8b814 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -22,7 +22,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclNamesp.c,v 1.201 2010/02/14 13:23:03 dkf Exp $ + * RCS: @(#) $Id: tclNamesp.c,v 1.202 2010/02/15 11:53:44 dkf Exp $ */ #include "tclInt.h" @@ -733,6 +733,7 @@ Tcl_CreateNamespace( nsPtr->commandPathLength = 0; nsPtr->commandPathArray = NULL; nsPtr->commandPathSourceList = NULL; + nsPtr->earlyDeleteProc = NULL; if (parentPtr != NULL) { entryPtr = Tcl_CreateHashEntry( @@ -844,6 +845,26 @@ Tcl_DeleteNamespace( Command *cmdPtr; /* + * Give anyone interested - notably TclOO - a chance to use this namespace + * normally despite the fact that the namespace is going to go. Allows the + * calling of destructors. Will only be called once (unless re-established + * by the called function). [Bug 2950259] + * + * Note that setting this field requires access to the internal definition + * of namespaces, so it should only be accessed by code that knows about + * being careful with reentrancy. + */ + + if (nsPtr->earlyDeleteProc != NULL) { + Tcl_NamespaceDeleteProc *earlyDeleteProc = nsPtr->earlyDeleteProc; + + nsPtr->earlyDeleteProc = NULL; + nsPtr->activationCount++; + earlyDeleteProc(nsPtr->clientData); + nsPtr->activationCount--; + } + + /* * Delete all coroutine commands now: break the circular ref cycle between * the namespace and the coroutine command [Bug 2724403]. This code is * essentially duplicated in TclTeardownNamespace() for all other |