summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandreas_kupries <akupries@shaw.ca>2009-10-07 23:10:50 (GMT)
committerandreas_kupries <akupries@shaw.ca>2009-10-07 23:10:50 (GMT)
commit817534697915bca720f02388c1e9b6a0e72718c0 (patch)
tree4e6a5262d6a5ff39a38b7e58e86be1407df4eb9f
parent86d7b6d7b9a8a46a9d99a3e0e6b707fe7eb0b411 (diff)
downloadtcl-817534697915bca720f02388c1e9b6a0e72718c0.zip
tcl-817534697915bca720f02388c1e9b6a0e72718c0.tar.gz
tcl-817534697915bca720f02388c1e9b6a0e72718c0.tar.bz2
* generic/tclObj.c: [Bug 2871908]: Plug memory leaks of the
objThreadMap and lineCLPtr hashtables. Also make the names of the continuation line information initialization and finalization functions more consistent. Patch supplied by Joe Mistachkin <joe@mistachkin.com>.
-rw-r--r--ChangeLog6
-rw-r--r--generic/tclEvent.c3
-rw-r--r--generic/tclObj.c73
3 files changed, 65 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 6d4f1b5..53932ec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2009-10-07 Andreas Kupries <andreask@activestate.com>
+ * generic/tclObj.c: [Bug 2871908]: Plug memory leaks of the
+ objThreadMap and lineCLPtr hashtables. Also make the names of the
+ continuation line information initialization and finalization
+ functions more consistent. Patch supplied by Joe Mistachkin
+ <joe@mistachkin.com>.
+
* generic/tclIORChan.c (ErrnoReturn): Replace the hardwired
constant 11 with the proper errno define, EAGAIN. What was I
thinking ? The BSD's have a different errno assignment and break
diff --git a/generic/tclEvent.c b/generic/tclEvent.c
index 299922f..a10da8f 100644
--- a/generic/tclEvent.c
+++ b/generic/tclEvent.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclEvent.c,v 1.80.2.1 2009/04/27 21:45:20 ferrieux Exp $
+ * RCS: @(#) $Id: tclEvent.c,v 1.80.2.2 2009/10/07 23:10:50 andreas_kupries Exp $
*/
#include "tclInt.h"
@@ -1239,6 +1239,7 @@ Tcl_FinalizeThread(void)
TclFinalizeIOSubsystem();
TclFinalizeNotifier();
TclFinalizeAsync();
+ TclFinalizeThreadObjects();
}
/*
diff --git a/generic/tclObj.c b/generic/tclObj.c
index 1b0a58c..39b8515 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclObj.c,v 1.139.2.3 2009/08/25 21:01:05 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclObj.c,v 1.139.2.4 2009/10/07 23:10:50 andreas_kupries Exp $
*/
#include "tclInt.h"
@@ -88,8 +88,8 @@ typedef struct ThreadSpecificData {
static Tcl_ThreadDataKey dataKey;
static void ContLineLocFree (char* clientData);
-static void TclThreadFinalizeObjects (ClientData clientData);
-static ThreadSpecificData* TclGetTables (void);
+static void TclThreadFinalizeContLines (ClientData clientData);
+static ThreadSpecificData* TclGetContLineTable (void);
/*
* Nested Tcl_Obj deletion management support
@@ -410,6 +410,49 @@ TclInitObjSubsystem(void)
/*
*----------------------------------------------------------------------
*
+ * TclFinalizeThreadObjects --
+ *
+ * This function is called by Tcl_FinalizeThread to clean up thread
+ * specific Tcl_Obj information.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeThreadObjects(void)
+{
+#if defined(TCL_MEM_DEBUG) && defined(TCL_THREADS)
+ Tcl_HashEntry *hPtr;
+ Tcl_HashSearch hSearch;
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ Tcl_HashTable *tablePtr = tsdPtr->objThreadMap;
+
+ if (tablePtr != NULL) {
+ for (hPtr = Tcl_FirstHashEntry(tablePtr, &hSearch);
+ hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) {
+ ObjData *objData = Tcl_GetHashValue(hPtr);
+
+ if (objData != NULL) {
+ ckfree((char *) objData);
+ }
+ }
+
+ Tcl_DeleteHashTable(tablePtr);
+ ckfree((char *) tablePtr);
+ tsdPtr->objThreadMap = NULL;
+ }
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclFinalizeObjects --
*
* This function is called by Tcl_Finalize to clean up all registered
@@ -447,7 +490,7 @@ TclFinalizeObjects(void)
/*
*----------------------------------------------------------------------
*
- * TclGetTables --
+ * TclGetContLineTable --
*
* This procedure is a helper which returns the thread-specific
* hash-table used to track continuation line information associated with
@@ -464,7 +507,7 @@ TclFinalizeObjects(void)
*/
static ThreadSpecificData*
-TclGetTables()
+TclGetContLineTable()
{
/*
* Initialize the hashtable tracking invisible continuation lines. For
@@ -478,10 +521,7 @@ TclGetTables()
if (!tsdPtr->lineCLPtr) {
tsdPtr->lineCLPtr = (Tcl_HashTable*) ckalloc (sizeof (Tcl_HashTable));
Tcl_InitHashTable(tsdPtr->lineCLPtr, TCL_ONE_WORD_KEYS);
- Tcl_CreateThreadExitHandler (TclThreadFinalizeObjects,NULL);
-#if defined(TCL_MEM_DEBUG) && defined(TCL_THREADS)
- tsdPtr->objThreadMap = NULL;
-#endif /* TCL_MEM_DEBUG && TCL_THREADS */
+ Tcl_CreateThreadExitHandler (TclThreadFinalizeContLines,NULL);
}
return tsdPtr;
}
@@ -510,7 +550,7 @@ TclContinuationsEnter(Tcl_Obj* objPtr,
int* loc)
{
int newEntry;
- ThreadSpecificData *tsdPtr = TclGetTables();
+ ThreadSpecificData *tsdPtr = TclGetContLineTable();
Tcl_HashEntry* hPtr =
Tcl_CreateHashEntry (tsdPtr->lineCLPtr, (char*) objPtr, &newEntry);
@@ -641,7 +681,7 @@ TclContinuationsEnterDerived(Tcl_Obj* objPtr, int start, int* clNext)
void
TclContinuationsCopy(Tcl_Obj* objPtr, Tcl_Obj* originObjPtr)
{
- ThreadSpecificData *tsdPtr = TclGetTables();
+ ThreadSpecificData *tsdPtr = TclGetContLineTable();
Tcl_HashEntry* hPtr = Tcl_FindHashEntry (tsdPtr->lineCLPtr, (char*) originObjPtr);
if (hPtr) {
@@ -673,7 +713,7 @@ TclContinuationsCopy(Tcl_Obj* objPtr, Tcl_Obj* originObjPtr)
ContLineLoc*
TclContinuationsGet(Tcl_Obj* objPtr)
{
- ThreadSpecificData *tsdPtr = TclGetTables();
+ ThreadSpecificData *tsdPtr = TclGetContLineTable();
Tcl_HashEntry* hPtr = Tcl_FindHashEntry (tsdPtr->lineCLPtr, (char*) objPtr);
if (hPtr) {
@@ -686,7 +726,7 @@ TclContinuationsGet(Tcl_Obj* objPtr)
/*
*----------------------------------------------------------------------
*
- * TclThreadFinalizeObjects --
+ * TclThreadFinalizeContLines --
*
* This procedure is a helper which releases all continuation line
* information currently known. It is run as a thread exit handler.
@@ -702,15 +742,15 @@ TclContinuationsGet(Tcl_Obj* objPtr)
*/
static void
-TclThreadFinalizeObjects (ClientData clientData)
+TclThreadFinalizeContLines (ClientData clientData)
{
/*
* Release the hashtable tracking invisible continuation lines.
*/
+ ThreadSpecificData *tsdPtr = TclGetContLineTable();
Tcl_HashEntry *hPtr;
Tcl_HashSearch hSearch;
- ThreadSpecificData *tsdPtr = TclGetTables();
for (hPtr = Tcl_FirstHashEntry(tsdPtr->lineCLPtr, &hSearch);
hPtr != NULL;
@@ -725,6 +765,7 @@ TclThreadFinalizeObjects (ClientData clientData)
Tcl_DeleteHashEntry (hPtr);
}
Tcl_DeleteHashTable (tsdPtr->lineCLPtr);
+ ckfree((char *) tsdPtr->lineCLPtr);
tsdPtr->lineCLPtr = NULL;
}
@@ -956,7 +997,7 @@ TclDbInitNewObj(
Tcl_HashEntry *hPtr;
Tcl_HashTable *tablePtr;
int isNew;
- ThreadSpecificData *tsdPtr = TclGetTables();
+ ThreadSpecificData *tsdPtr = TclGetContLineTable();
if (tsdPtr->objThreadMap == NULL) {
tsdPtr->objThreadMap = (Tcl_HashTable *)