summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2010-01-03 20:29:11 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2010-01-03 20:29:11 (GMT)
commit10428413079058e0f75d48d4f976493454730d0b (patch)
treedce88a02399c32caf6d59948227d30e00d697a4d /generic
parentd20cf874f1303bf21f722abb01c7d1f08a9dc251 (diff)
downloadtcl-10428413079058e0f75d48d4f976493454730d0b.zip
tcl-10428413079058e0f75d48d4f976493454730d0b.tar.gz
tcl-10428413079058e0f75d48d4f976493454730d0b.tar.bz2
* generic/tclBasic.c: Fix lerak of coroutines on namespace
* generic/tclCompile.h: deletion, [Bug 2724403]. Added a test * generic/tclNamesp.c: for this leak, and also a test for * tests/coroutine.test: leaks on namespace deletion. * tests/namespace.test:
Diffstat (limited to 'generic')
-rw-r--r--generic/tclBasic.c5
-rw-r--r--generic/tclCompile.h3
-rw-r--r--generic/tclNamesp.c26
3 files changed, 29 insertions, 5 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 43f484b..254760d 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -16,7 +16,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclBasic.c,v 1.437 2009/12/24 06:55:25 dkf Exp $
+ * RCS: @(#) $Id: tclBasic.c,v 1.438 2010/01/03 20:29:11 msofer Exp $
*/
#include "tclInt.h"
@@ -137,7 +137,6 @@ static Tcl_Obj * GetCommandSource(Interp *iPtr, int objc,
Tcl_Obj *const objv[], int lookup);
static void MathFuncWrongNumArgs(Tcl_Interp *interp, int expected,
int actual, Tcl_Obj *const *objv);
-static Tcl_ObjCmdProc NRInterpCoroutine;
static Tcl_NRPostProc NRCoroutineCallerCallback;
static Tcl_NRPostProc NRCoroutineExitCallback;
static Tcl_NRPostProc NRRunObjProc;
@@ -8674,7 +8673,7 @@ NRCoroutineExitCallback(
return result;
}
-static int
+int
NRInterpCoroutine(
ClientData clientData,
Tcl_Interp *interp, /* Current interpreter. */
diff --git a/generic/tclCompile.h b/generic/tclCompile.h
index 25dec86..a41e094 100644
--- a/generic/tclCompile.h
+++ b/generic/tclCompile.h
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclCompile.h,v 1.119 2009/09/04 17:33:11 dgp Exp $
+ * RCS: @(#) $Id: tclCompile.h,v 1.120 2010/01/03 20:29:11 msofer Exp $
*/
#ifndef _TCLCOMPILATION
@@ -858,6 +858,7 @@ typedef struct {
MODULE_SCOPE Tcl_NRPostProc NRCallTEBC;
MODULE_SCOPE Tcl_NRPostProc NRCommand;
+MODULE_SCOPE Tcl_ObjCmdProc NRInterpCoroutine;
#define TCL_NR_BC_TYPE 0
#define TCL_NR_ATEXIT_TYPE 1
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c
index 507007d..f8ee460 100644
--- a/generic/tclNamesp.c
+++ b/generic/tclNamesp.c
@@ -23,7 +23,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.198 2009/12/13 17:11:47 msofer Exp $
+ * RCS: @(#) $Id: tclNamesp.c,v 1.199 2010/01/03 20:29:11 msofer Exp $
*/
#include "tclInt.h"
@@ -956,7 +956,31 @@ Tcl_DeleteNamespace(
Namespace *globalNsPtr = (Namespace *)
TclGetGlobalNamespace((Tcl_Interp *) iPtr);
Tcl_HashEntry *entryPtr;
+ Tcl_HashSearch search;
+ Command *cmdPtr;
+
+ /*
+ * 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
+ * commands. Don't optimize to Tcl_NextHashEntry() because of traces.
+ *
+ * NOTE: we could avoid traversing the ns's command list by keeping a
+ * separate list of coros.
+ */
+ for (entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+ entryPtr != NULL;) {
+ cmdPtr = (Command *) Tcl_GetHashValue(entryPtr);
+ if (cmdPtr->nreProc == NRInterpCoroutine) {
+ Tcl_DeleteCommandFromToken((Tcl_Interp *) iPtr, (Tcl_Command)cmdPtr);
+ entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+ } else {
+ entryPtr = entryPtr->nextPtr;
+ }
+ }
+
+
/*
* If the namespace has associated ensemble commands, delete them first.
* This leaves the actual contents of the namespace alone (unless they are