Attachment "bug736426.diff" to
ticket [736426ffff]
added by
mistachkin
2004-07-16 10:16:21.
Index: generic/tclEvent.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclEvent.c,v
retrieving revision 1.43
diff -b -u -r1.43 tclEvent.c
--- generic/tclEvent.c 15 Jul 2004 20:04:38 -0000 1.43
+++ generic/tclEvent.c 16 Jul 2004 02:58:12 -0000
@@ -973,7 +973,9 @@
/*
* There shouldn't be any malloc'ed memory after this.
*/
-
+#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
+ TclFinalizeThreadAlloc();
+#endif
TclFinalizeMemorySubsystem();
inFinalize = 0;
}
Index: generic/tclInt.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclInt.h,v
retrieving revision 1.168
diff -b -u -r1.168 tclInt.h
--- generic/tclInt.h 7 Jul 2004 08:21:26 -0000 1.168
+++ generic/tclInt.h 16 Jul 2004 02:58:17 -0000
@@ -2361,6 +2361,8 @@
EXTERN Tcl_Mutex *TclpNewAllocMutex _ANSI_ARGS_((void));
EXTERN void *TclpGetAllocCache _ANSI_ARGS_((void));
EXTERN void TclpSetAllocCache _ANSI_ARGS_((void *));
+EXTERN void TclFinalizeThreadAlloc _ANSI_ARGS_((void));
+EXTERN void TclpFreeAllocMutex _ANSI_ARGS_((Tcl_Mutex* mutex));
# define TclAllocObjStorage(objPtr) \
(objPtr) = TclThreadAllocObj()
Index: generic/tclThreadAlloc.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclThreadAlloc.c,v
retrieving revision 1.13
diff -b -u -r1.13 tclThreadAlloc.c
--- generic/tclThreadAlloc.c 21 Jun 2004 08:54:34 -0000 1.13
+++ generic/tclThreadAlloc.c 16 Jul 2004 02:58:17 -0000
@@ -957,4 +957,62 @@
return 1;
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeThreadAlloc --
+ *
+ * This procedure is used to destroy all private resources used in
+ * this file.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeThreadAlloc()
+{
+ int i;
+ for (i = 0; i < NBUCKETS; ++i) {
+ TclpFreeAllocMutex(bucketInfo[i].lockPtr);
+ bucketInfo[i].lockPtr = NULL;
+ }
+
+ TclpFreeAllocMutex(objLockPtr);
+ objLockPtr = NULL;
+
+ TclpFreeAllocMutex(listLockPtr);
+ listLockPtr = NULL;
+}
+
+#else
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeThreadAlloc --
+ *
+ * This procedure is used to destroy all private resources used in
+ * this file.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeThreadAlloc()
+{
+ Tcl_Panic("TclFinalizeThreadAlloc called when threaded memory allocator not in use.");
+}
+
#endif /* TCL_THREADS */
Index: unix/tclUnixThrd.c
===================================================================
RCS file: /cvsroot/tcl/tcl/unix/tclUnixThrd.c,v
retrieving revision 1.33
diff -b -u -r1.33 tclUnixThrd.c
--- unix/tclUnixThrd.c 15 Jul 2004 22:04:43 -0000 1.33
+++ unix/tclUnixThrd.c 16 Jul 2004 02:58:19 -0000
@@ -938,15 +938,17 @@
static pthread_key_t key;
static pthread_once_t once = PTHREAD_ONCE_INIT;
+typedef struct allocMutex {
+ Tcl_Mutex tlock;
+ pthread_mutex_t plock;
+} allocMutex;
+
Tcl_Mutex *
TclpNewAllocMutex(void)
{
- struct lock {
- Tcl_Mutex tlock;
- pthread_mutex_t plock;
- } *lockPtr;
+ struct allocMutex *lockPtr;
- lockPtr = malloc(sizeof(struct lock));
+ lockPtr = malloc(sizeof(struct allocMutex));
if (lockPtr == NULL) {
Tcl_Panic("could not allocate lock");
}
@@ -955,15 +957,45 @@
return &lockPtr->tlock;
}
-static void
-InitKey(void)
+void
+TclpFreeAllocMutex(mutex)
+ Tcl_Mutex *mutex; /* The alloc mutex to free. */
+{
+ allocMutex* lockPtr = (allocMutex*) mutex;
+ if (!lockPtr) return;
+ pthread_mutex_destroy(&lockPtr->plock);
+ free(lockPtr);
+}
+
+void TclpFreeAllocCache(ptr)
+ void *ptr;
{
extern void TclFreeAllocCache(void *);
- pthread_key_create(&key, TclFreeAllocCache);
+ TclFreeAllocCache(ptr);
+ FreeKey();
+}
+
+static void
+InitKey(void)
+{
+ pthread_key_create(&key, TclpFreeAllocCache);
initialized = 1;
}
+static void
+FreeKey(void)
+{
+ /*
+ * Perform proper cleanup of things done in InitKey.
+ */
+ if (initialized) {
+ pthread_key_delete(key);
+ once = PTHREAD_ONCE_INIT;
+ initialized = 0;
+ }
+}
+
void *
TclpGetAllocCache(void)
{
Index: win/tclWinThrd.c
===================================================================
RCS file: /cvsroot/tcl/tcl/win/tclWinThrd.c,v
retrieving revision 1.31
diff -b -u -r1.31 tclWinThrd.c
--- win/tclWinThrd.c 22 Jun 2004 13:09:01 -0000 1.31
+++ win/tclWinThrd.c 16 Jul 2004 02:58:20 -0000
@@ -1038,17 +1038,20 @@
* Additions by AOL for specialized thread memory allocator.
*/
#ifdef USE_THREAD_ALLOC
+static int once;
static DWORD key;
+typedef struct allocMutex {
+ Tcl_Mutex tlock;
+ CRITICAL_SECTION wlock;
+} allocMutex;
+
Tcl_Mutex *
TclpNewAllocMutex(void)
{
- struct lock {
- Tcl_Mutex tlock;
- CRITICAL_SECTION wlock;
- } *lockPtr;
+ struct allocMutex *lockPtr;
- lockPtr = malloc(sizeof(struct lock));
+ lockPtr = malloc(sizeof(struct allocMutex));
if (lockPtr == NULL) {
Tcl_Panic("could not allocate lock");
}
@@ -1057,10 +1060,19 @@
return &lockPtr->tlock;
}
+void
+TclpFreeAllocMutex(mutex)
+ Tcl_Mutex *mutex; /* The alloc mutex to free. */
+{
+ allocMutex* lockPtr = (allocMutex*) mutex;
+ if (!lockPtr) return;
+ DeleteCriticalSection(&lockPtr->wlock);
+ free(lockPtr);
+}
+
void *
TclpGetAllocCache(void)
{
- static int once = 0;
VOID *result;
if (!once) {
@@ -1111,6 +1123,15 @@
Tcl_Panic("TlsGetValue failed from TclWinFreeAllocCache!");
}
}
+
+ if (once) {
+ success = TlsFree(key);
+ if (!success) {
+ Tcl_Panic("TlsFree failed from TclWinFreeAllocCache!");
+ }
+
+ once = 0; /* reset for next time. */
+ }
}
#endif /* USE_THREAD_ALLOC */