summaryrefslogtreecommitdiffstats
path: root/generic/tclNamesp.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2010-02-15 11:53:43 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2010-02-15 11:53:43 (GMT)
commita0d1a202239c64ab548f9d515bba530fb475d743 (patch)
tree58ef89d3285974776896099a22e8bea82da7cef4 /generic/tclNamesp.c
parent2a083e870cd9bd162468f535c9a9b724516353ea (diff)
downloadtcl-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.c23
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