summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandreas_kupries <akupries@shaw.ca>2003-04-25 20:02:36 (GMT)
committerandreas_kupries <akupries@shaw.ca>2003-04-25 20:02:36 (GMT)
commitbb1ae65db1a29d83933c869fec4200fddf6c615a (patch)
tree3d9a2e319ba50cd2006ffbecdfb8eb897ae5be3e
parent18cd8fbc6f64e08f50f389af9201c9fbd4498b3b (diff)
downloadtcl-bb1ae65db1a29d83933c869fec4200fddf6c615a.zip
tcl-bb1ae65db1a29d83933c869fec4200fddf6c615a.tar.gz
tcl-bb1ae65db1a29d83933c869fec4200fddf6c615a.tar.bz2
* 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).
-rw-r--r--ChangeLog11
-rw-r--r--win/tclWinThrd.c63
2 files changed, 65 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index b063674..4461127 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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!");
+ }
}
}