diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | win/tclWinThrd.c | 63 |
2 files changed, 65 insertions, 9 deletions
@@ -1,3 +1,14 @@ +2003-04-25 Andreas Kupries <andreask@activestate.com> + + * win/tclWinThrd.c: Applied SF patch #727271. This patch changes + the code to catch any errors returned by the windows functions + handling TLS ASAP instead of waiting to get some mysterious + crash later on due to bogus pointers. Patch provided by Joe + Mistachkin. + + This is a stop-gap measure to deal with the low number of ?TLS + slots provided by some of the variants of Windows (60-80). + 2003-04-21 Don Porter <dgp@users.sourceforge.net> * library/tcltest/tcltest.tcl: When the return code of a test does diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c index f0ee02c..b8c045e 100644 --- a/win/tclWinThrd.c +++ b/win/tclWinThrd.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinThrd.c,v 1.24 2003/01/14 02:06:11 mdejong Exp $ + * RCS: @(#) $Id: tclWinThrd.c,v 1.24.2.1 2003/04/25 20:02:39 andreas_kupries Exp $ */ #include "tclWinInt.h" @@ -539,11 +539,17 @@ TclpThreadDataKeyInit(keyPtr) * really (DWORD **) */ { DWORD *indexPtr; + DWORD newKey; MASTER_LOCK; if (*keyPtr == NULL) { indexPtr = (DWORD *)ckalloc(sizeof(DWORD)); - *indexPtr = TlsAlloc(); + newKey = TlsAlloc(); + if (newKey != TLS_OUT_OF_INDEXES) { + *indexPtr = newKey; + } else { + panic("TlsAlloc failed from TclpThreadDataKeyInit!"); /* this should be a fatal error */ + } *keyPtr = (Tcl_ThreadDataKey)indexPtr; TclRememberDataKey(keyPtr); } @@ -573,10 +579,15 @@ TclpThreadDataKeyGet(keyPtr) * really (DWORD **) */ { DWORD *indexPtr = *(DWORD **)keyPtr; + LPVOID result; if (indexPtr == NULL) { return NULL; } else { - return (VOID *) TlsGetValue(*indexPtr); + result = TlsGetValue(*indexPtr); + if ((result == NULL) && (GetLastError() != NO_ERROR)) { + panic("TlsGetValue failed from TclpThreadDataKeyGet!"); + } + return result; } } @@ -604,7 +615,11 @@ TclpThreadDataKeySet(keyPtr, data) VOID *data; /* Thread local storage */ { DWORD *indexPtr = *(DWORD **)keyPtr; - TlsSetValue(*indexPtr, (void *)data); + BOOL success; + success = TlsSetValue(*indexPtr, (void *)data); + if (!success) { + panic("TlsSetValue failed from TclpThreadDataKeySet!"); + } } /* @@ -630,6 +645,7 @@ TclpFinalizeThreadData(keyPtr) { VOID *result; DWORD *indexPtr; + BOOL success; #ifdef USE_THREAD_ALLOC TclWinFreeAllocCache(); @@ -639,7 +655,14 @@ TclpFinalizeThreadData(keyPtr) result = (VOID *)TlsGetValue(*indexPtr); if (result != NULL) { ckfree((char *)result); - TlsSetValue(*indexPtr, (void *)NULL); + success = TlsSetValue(*indexPtr, (void *)NULL); + if (!success) { + panic("TlsSetValue failed from TclpFinalizeThreadData!"); + } + } else { + if (GetLastError() != NO_ERROR) { + panic("TlsGetValue failed from TclpFinalizeThreadData!"); + } } } } @@ -669,9 +692,13 @@ TclpFinalizeThreadDataKey(keyPtr) Tcl_ThreadDataKey *keyPtr; { DWORD *indexPtr; + BOOL success; if (*keyPtr != NULL) { indexPtr = *(DWORD **)keyPtr; - TlsFree(*indexPtr); + success = TlsFree(*indexPtr); + if (!success) { + panic("TlsFree failed from TclpFinalizeThreadDataKey!"); + } ckfree((char *)indexPtr); *keyPtr = NULL; } @@ -1001,6 +1028,7 @@ void * TclpGetAllocCache(void) { static int once = 0; + VOID *result; if (!once) { /* @@ -1014,24 +1042,41 @@ TclpGetAllocCache(void) panic("could not allocate thread local storage"); } } - return TlsGetValue(key); + + result = TlsGetValue(key); + if ((result == NULL) && (GetLastError() != NO_ERROR)) { + panic("TlsGetValue failed from TclpGetAllocCache!"); + } + return result; } void TclpSetAllocCache(void *ptr) { - TlsSetValue(key, ptr); + BOOL success; + success = TlsSetValue(key, ptr); + if (!success) { + panic("TlsSetValue failed from TclpSetAllocCache!"); + } } void TclWinFreeAllocCache(void) { void *ptr; + BOOL success; ptr = TlsGetValue(key); if (ptr != NULL) { - TlsSetValue(key, NULL); + success = TlsSetValue(key, NULL); + if (!success) { + panic("TlsSetValue failed from TclWinFreeAllocCache!"); + } TclFreeAllocCache(ptr); + } else { + if (GetLastError() != NO_ERROR) { + panic("TlsGetValue failed from TclWinFreeAllocCache!"); + } } } |