diff options
-rw-r--r-- | generic/tclEvent.c | 3 | ||||
-rw-r--r-- | generic/tclInt.h | 3 | ||||
-rw-r--r-- | unix/tclUnixThrd.c | 27 | ||||
-rw-r--r-- | win/tclWinNotify.c | 26 | ||||
-rw-r--r-- | win/tclWinThrd.c | 33 |
5 files changed, 49 insertions, 43 deletions
diff --git a/generic/tclEvent.c b/generic/tclEvent.c index 8305410..d62850b 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -1043,6 +1043,9 @@ TclInitSubsystems(void) #if USE_TCLALLOC TclInitAlloc(); /* Process wide mutex init */ #endif +#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC) + TclpInitThreadAlloc(); +#endif #ifdef TCL_MEM_DEBUG TclInitDbCkalloc(); /* Process wide mutex init */ #endif diff --git a/generic/tclInt.h b/generic/tclInt.h index 42c13dd..d481cde 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3146,6 +3146,9 @@ MODULE_SCOPE int TclpLoadMemory(Tcl_Interp *interp, void *buffer, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); #endif MODULE_SCOPE void TclInitThreadStorage(void); +#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC) +MODULE_SCOPE void TclpInitThreadAlloc(void); +#endif MODULE_SCOPE void TclFinalizeThreadDataThread(void); MODULE_SCOPE void TclFinalizeThreadStorage(void); #ifdef TCL_WIDE_CLICKS diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index 554a2dc..070a107 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -673,7 +673,6 @@ TclpInetNtoa( */ #ifdef USE_THREAD_ALLOC -static volatile int initialized = 0; static pthread_key_t key; typedef struct allocMutex { @@ -720,29 +719,23 @@ TclpFreeAllocCache( TclFreeAllocCache(ptr); pthread_setspecific(key, NULL); - - } else if (initialized) { - /* - * Called by us in TclFinalizeThreadAlloc() during the library - * finalization initiated from Tcl_Finalize() - */ - + + } else { pthread_key_delete(key); - initialized = 0; } } +void +TclpInitThreadAlloc(void) +{ + pthread_mutex_lock(allocLockPtr); + pthread_key_create(&key, TclpFreeAllocCache); + pthread_mutex_unlock(allocLockPtr); +} + void * TclpGetAllocCache(void) { - if (!initialized) { - pthread_mutex_lock(allocLockPtr); - if (!initialized) { - pthread_key_create(&key, TclpFreeAllocCache); - initialized = 1; - } - pthread_mutex_unlock(allocLockPtr); - } return pthread_getspecific(key); } diff --git a/win/tclWinNotify.c b/win/tclWinNotify.c index ea4035b..1ad022d 100644 --- a/win/tclWinNotify.c +++ b/win/tclWinNotify.c @@ -51,7 +51,8 @@ static Tcl_ThreadDataKey dataKey; static int notifierCount = 0; static const TCHAR className[] = TEXT("TclNotifier"); -TCL_DECLARE_MUTEX(notifierMutex) +static int initialized = 0; +static CRITICAL_SECTION notifierMutex; /* * Static routines defined in this file. @@ -85,12 +86,19 @@ Tcl_InitNotifier(void) ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); WNDCLASS class; + TclpMasterLock(); + if (!initialized) { + initialized = 1; + InitializeCriticalSection(¬ifierMutex); + } + TclpMasterUnlock(); + /* * Register Notifier window class if this is the first thread to use * this module. */ - Tcl_MutexLock(¬ifierMutex); + EnterCriticalSection(¬ifierMutex); if (notifierCount == 0) { class.style = 0; class.cbClsExtra = 0; @@ -108,7 +116,7 @@ Tcl_InitNotifier(void) } } notifierCount++; - Tcl_MutexUnlock(¬ifierMutex); + LeaveCriticalSection(¬ifierMutex); tsdPtr->pending = 0; tsdPtr->timerActive = 0; @@ -183,12 +191,14 @@ Tcl_FinalizeNotifier( * notifier window class. */ - Tcl_MutexLock(¬ifierMutex); - notifierCount--; - if (notifierCount == 0) { - UnregisterClass(className, TclWinGetTclInstance()); + EnterCriticalSection(¬ifierMutex); + if (notifierCount) { + notifierCount--; + if (notifierCount == 0) { + UnregisterClass(className, TclWinGetTclInstance()); + } } - Tcl_MutexUnlock(¬ifierMutex); + LeaveCriticalSection(¬ifierMutex); } } diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c index e44363b..8791c19 100644 --- a/win/tclWinThrd.c +++ b/win/tclWinThrd.c @@ -119,7 +119,6 @@ typedef struct WinCondition { */ #ifdef USE_THREAD_ALLOC -static int once; static DWORD tlsKey; typedef struct allocMutex { @@ -968,24 +967,24 @@ TclpFreeAllocMutex( free(lockPtr); } +void +TclpInitThreadAlloc(void) +{ + /* + * We need to make sure that TclpFreeAllocCache is called on each + * thread that calls this, but only on threads that call this. + */ + + tlsKey = TlsAlloc(); + if (tlsKey == TLS_OUT_OF_INDEXES) { + Tcl_Panic("could not allocate thread local storage"); + } +} + void * TclpGetAllocCache(void) { void *result; - - if (!once) { - /* - * We need to make sure that TclpFreeAllocCache is called on each - * thread that calls this, but only on threads that call this. - */ - - tlsKey = TlsAlloc(); - once = 1; - if (tlsKey == TLS_OUT_OF_INDEXES) { - Tcl_Panic("could not allocate thread local storage"); - } - } - result = TlsGetValue(tlsKey); if ((result == NULL) && (GetLastError() != NO_ERROR)) { Tcl_Panic("TlsGetValue failed from TclpGetAllocCache"); @@ -1021,7 +1020,7 @@ TclpFreeAllocCache( if (!success) { Tcl_Panic("TlsSetValue failed from TclpFreeAllocCache"); } - } else if (once) { + } else { /* * Called by us in TclFinalizeThreadAlloc() during the library * finalization initiated from Tcl_Finalize() @@ -1031,9 +1030,7 @@ TclpFreeAllocCache( if (!success) { Tcl_Panic("TlsFree failed from TclpFreeAllocCache"); } - once = 0; /* reset for next time. */ } - } #endif /* USE_THREAD_ALLOC */ |