summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-04-24 04:34:01 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-04-24 04:34:01 (GMT)
commit5b5f0209a4f6007ff2804da3f32258bb2148e814 (patch)
tree7c825dbeded76cc60fc9770c7f9d97f008323262
parent333fb43fbfb982a67285d944fe45a42dc8f85913 (diff)
parentfe4debabde73db9d51c655f61d19bc8d23956668 (diff)
downloadtcl-5b5f0209a4f6007ff2804da3f32258bb2148e814.zip
tcl-5b5f0209a4f6007ff2804da3f32258bb2148e814.tar.gz
tcl-5b5f0209a4f6007ff2804da3f32258bb2148e814.tar.bz2
[3493120] Plug memory leak in thread exit.
-rw-r--r--generic/tclInt.h1
-rw-r--r--generic/tclThread.c8
-rw-r--r--generic/tclThreadAlloc.c27
-rw-r--r--unix/tclUnixThrd.c1
4 files changed, 35 insertions, 2 deletions
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 2aa1725..7b1f5bf 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -2896,6 +2896,7 @@ MODULE_SCOPE void TclFinalizeObjects(void);
MODULE_SCOPE void TclFinalizePreserve(void);
MODULE_SCOPE void TclFinalizeSynchronization(void);
MODULE_SCOPE void TclFinalizeThreadAlloc(void);
+MODULE_SCOPE void TclFinalizeThreadAllocThread(void);
MODULE_SCOPE void TclFinalizeThreadData(void);
MODULE_SCOPE void TclFinalizeThreadObjects(void);
MODULE_SCOPE double TclFloor(const mp_int *a);
diff --git a/generic/tclThread.c b/generic/tclThread.c
index d1f2691..8c972a8 100644
--- a/generic/tclThread.c
+++ b/generic/tclThread.c
@@ -339,8 +339,9 @@ Tcl_ConditionFinalize(
*
* TclFinalizeThreadData --
*
- * This function cleans up the thread-local storage. This is called once
- * for each thread.
+ * This function cleans up the thread-local storage. Secondary, it cleans
+ * thread alloc cache.
+ * This is called once for each thread before thread exits.
*
* Results:
* None.
@@ -355,6 +356,9 @@ void
TclFinalizeThreadData(void)
{
TclFinalizeThreadDataThread();
+#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
+ TclFinalizeThreadAllocThread();
+#endif
}
/*
diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c
index abd5af5..ddf888a 100644
--- a/generic/tclThreadAlloc.c
+++ b/generic/tclThreadAlloc.c
@@ -1023,6 +1023,33 @@ TclFinalizeThreadAlloc(void)
TclpFreeAllocCache(NULL);
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeThreadAllocThread --
+ *
+ * This procedure is used to destroy single thread private resources used
+ * in this file.
+ * Called in TclpFinalizeThreadData when a thread exits (Tcl_FinalizeThread).
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeThreadAllocThread(void)
+{
+ Cache *cachePtr = TclpGetAllocCache();
+ if (cachePtr != NULL) {
+ TclpFreeAllocCache(cachePtr);
+ }
+}
+
#else /* !(TCL_THREADS && USE_THREAD_ALLOC) */
/*
*----------------------------------------------------------------------
diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c
index f469341..d34bc88 100644
--- a/unix/tclUnixThrd.c
+++ b/unix/tclUnixThrd.c
@@ -727,6 +727,7 @@ TclpFreeAllocCache(
*/
TclFreeAllocCache(ptr);
+ pthread_setspecific(key, NULL);
} else if (initialized) {
/*