diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2017-01-16 11:57:17 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2017-01-16 11:57:17 (GMT) |
commit | 033b606d4a893a9cf750fb5fb89b733aa41c3d8c (patch) | |
tree | ef9865e112bac153d0d37550d465c63dcdb6f92c | |
parent | 9a41c99458c9f645f364789c7ac310f55c77eccc (diff) | |
parent | 8c5fe95e9cc4b8115124f0cd9a936f68e7247db1 (diff) | |
download | tcl-033b606d4a893a9cf750fb5fb89b733aa41c3d8c.zip tcl-033b606d4a893a9cf750fb5fb89b733aa41c3d8c.tar.gz tcl-033b606d4a893a9cf750fb5fb89b733aa41c3d8c.tar.bz2 |
Fix for missing proper initialization of the threaded allocator in some situations. Problem reported by Zoran Vasiljevic, only noted when building/running NaviServer/AOLServer with Tcl 8.7 (trunk).
-rw-r--r-- | generic/tclEvent.c | 2 | ||||
-rw-r--r-- | generic/tclInt.h | 1 | ||||
-rw-r--r-- | generic/tclThreadAlloc.c | 45 | ||||
-rw-r--r-- | unix/tclUnixThrd.c | 2 |
4 files changed, 37 insertions, 13 deletions
diff --git a/generic/tclEvent.c b/generic/tclEvent.c index 0eabc13..436db7a 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -1044,7 +1044,7 @@ TclInitSubsystems(void) TclInitAlloc(); /* Process wide mutex init */ #endif #if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC) - TclpInitAllocCache(); + TclInitThreadAlloc(); /* Setup thread allocator caches */ #endif #ifdef TCL_MEM_DEBUG TclInitDbCkalloc(); /* Process wide mutex init */ diff --git a/generic/tclInt.h b/generic/tclInt.h index dd0c11a..8516385 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2945,6 +2945,7 @@ MODULE_SCOPE void TclFinalizeNotifier(void); MODULE_SCOPE void TclFinalizeObjects(void); MODULE_SCOPE void TclFinalizePreserve(void); MODULE_SCOPE void TclFinalizeSynchronization(void); +MODULE_SCOPE void TclInitThreadAlloc(void); MODULE_SCOPE void TclFinalizeThreadAlloc(void); MODULE_SCOPE void TclFinalizeThreadAllocThread(void); MODULE_SCOPE void TclFinalizeThreadData(int quick); diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index 2ee758e..8077de4 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -196,20 +196,11 @@ GetCache(void) if (listLockPtr == NULL) { Tcl_Mutex *initLockPtr; - unsigned int i; initLockPtr = Tcl_GetAllocMutex(); Tcl_MutexLock(initLockPtr); if (listLockPtr == NULL) { - listLockPtr = TclpNewAllocMutex(); - objLockPtr = TclpNewAllocMutex(); - for (i = 0; i < NBUCKETS; ++i) { - bucketInfo[i].blockSize = MINALLOC << i; - bucketInfo[i].maxBlocks = 1 << (NBUCKETS - 1 - i); - bucketInfo[i].numMove = i < NBUCKETS - 1 ? - 1 << (NBUCKETS - 2 - i) : 1; - bucketInfo[i].lockPtr = TclpNewAllocMutex(); - } + TclInitThreadAlloc(); } Tcl_MutexUnlock(initLockPtr); } @@ -1064,6 +1055,40 @@ GetBlocks( } return 1; } + +/* + *---------------------------------------------------------------------- + * + * TclInitThreadAlloc -- + * + * Initializes the allocator cache-maintenance structures. + * It is done early and protected during the TclInitSubsystems(). + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TclInitThreadAlloc(void) +{ + unsigned int i; + + listLockPtr = TclpNewAllocMutex(); + objLockPtr = TclpNewAllocMutex(); + for (i = 0; i < NBUCKETS; ++i) { + bucketInfo[i].blockSize = MINALLOC << i; + bucketInfo[i].maxBlocks = 1 << (NBUCKETS - 1 - i); + bucketInfo[i].numMove = i < NBUCKETS - 1 ? + 1 << (NBUCKETS - 2 - i) : 1; + bucketInfo[i].lockPtr = TclpNewAllocMutex(); + } + TclpInitAllocCache(); +} /* *---------------------------------------------------------------------- diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index 7394545..805599d 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -711,9 +711,7 @@ TclpFreeAllocMutex( void TclpInitAllocCache(void) { - pthread_mutex_lock(allocLockPtr); pthread_key_create(&key, NULL); - pthread_mutex_unlock(allocLockPtr); } void |