diff options
author | Miguel Sofer <miguel.sofer@gmail.com> | 2010-01-03 20:29:11 (GMT) |
---|---|---|
committer | Miguel Sofer <miguel.sofer@gmail.com> | 2010-01-03 20:29:11 (GMT) |
commit | 10428413079058e0f75d48d4f976493454730d0b (patch) | |
tree | dce88a02399c32caf6d59948227d30e00d697a4d /generic | |
parent | d20cf874f1303bf21f722abb01c7d1f08a9dc251 (diff) | |
download | tcl-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.c | 5 | ||||
-rw-r--r-- | generic/tclCompile.h | 3 | ||||
-rw-r--r-- | generic/tclNamesp.c | 26 |
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 |