aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2011-08-28 17:21:01 -0700
committerChris Robinson <[email protected]>2011-08-28 17:21:01 -0700
commit5eceb593e9cfd57611e99217e2f9c346bb10305c (patch)
treee24bef2ea66470eabd8c8f2dfe19c8e38e7dc45a
parent82244f298ced5fd96dec5ee64c8a5b957b7dfdb4 (diff)
Emulate pthread TLS functions in Windows
-rw-r--r--Alc/ALc.c40
-rw-r--r--Alc/helpers.c26
-rw-r--r--OpenAL32/Include/alMain.h50
3 files changed, 78 insertions, 38 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index d7ddc15c..869bafb8 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -367,7 +367,7 @@ static ALCcontext *g_pContextList = NULL;
static ALCuint g_ulContextCount = 0;
// Thread-local current context
-static tls_type LocalContext;
+static pthread_key_t LocalContext;
// Process-wide current context
static ALCcontext *GlobalContext;
@@ -421,21 +421,37 @@ static void alc_deinit(void);
static void alc_deinit_safe(void);
#ifndef AL_LIBTYPE_STATIC
+UIntMap TlsDestructor;
+
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
+ ALsizei i;
+ (void)hModule;
+
// Perform actions based on the reason for calling.
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
- DisableThreadLibraryCalls(hModule);
+ InitUIntMap(&TlsDestructor);
alc_init();
break;
+ case DLL_THREAD_DETACH:
+ for(i = 0;i < TlsDestructor.size;i++)
+ {
+ void *ptr = pthread_getspecific(TlsDestructor.array[i].key);
+ void (*callback)(void*) = (void(*)(void*))TlsDestructor.array[i].value;
+ if(ptr && callback)
+ callback(ptr);
+ }
+ break;
+
case DLL_PROCESS_DETACH:
if(!lpReserved)
alc_deinit();
else
alc_deinit_safe();
+ ResetUIntMap(&TlsDestructor);
break;
}
return TRUE;
@@ -483,7 +499,7 @@ static void alc_init(void)
if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
ZScale = -1.0;
- tls_create(&LocalContext);
+ pthread_key_create(&LocalContext, NULL);
InitializeCriticalSection(&ListLock);
ThunkInit();
}
@@ -496,7 +512,7 @@ static void alc_deinit_safe(void)
ThunkExit();
DeleteCriticalSection(&ListLock);
- tls_delete(LocalContext);
+ pthread_key_delete(LocalContext);
if(LogFile != stderr)
fclose(LogFile);
@@ -1295,10 +1311,10 @@ ALCcontext *GetLockedContext(void)
LockLists();
- pContext = tls_get(LocalContext);
+ pContext = pthread_getspecific(LocalContext);
if(pContext && !IsContext(pContext))
{
- tls_set(LocalContext, NULL);
+ pthread_setspecific(LocalContext, NULL);
pContext = NULL;
}
if(!pContext)
@@ -2125,10 +2141,10 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(ALCvoid)
ALCcontext *Context;
LockLists();
- Context = tls_get(LocalContext);
+ Context = pthread_getspecific(LocalContext);
if(Context && !IsContext(Context))
{
- tls_set(LocalContext, NULL);
+ pthread_setspecific(LocalContext, NULL);
Context = NULL;
}
if(!Context)
@@ -2149,10 +2165,10 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
LockLists();
- pContext = tls_get(LocalContext);
+ pContext = pthread_getspecific(LocalContext);
if(pContext && !IsContext(pContext))
{
- tls_set(LocalContext, NULL);
+ pthread_setspecific(LocalContext, NULL);
pContext = NULL;
}
@@ -2197,7 +2213,7 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
if(context == NULL || IsContext(context))
{
GlobalContext = context;
- tls_set(LocalContext, NULL);
+ pthread_setspecific(LocalContext, NULL);
}
else
{
@@ -2223,7 +2239,7 @@ ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
// context must be a valid Context or NULL
if(context == NULL || IsContext(context))
- tls_set(LocalContext, context);
+ pthread_setspecific(LocalContext, context);
else
{
alcSetError(NULL, ALC_INVALID_CONTEXT);
diff --git a/Alc/helpers.c b/Alc/helpers.c
index 43ab43b9..85433368 100644
--- a/Alc/helpers.c
+++ b/Alc/helpers.c
@@ -59,6 +59,32 @@ void pthread_once(pthread_once_t *once, void (*callback)(void))
InterlockedExchange(once, 2);
}
+
+int pthread_key_create(pthread_key_t *key, void (*callback)(void*))
+{
+ *key = TlsAlloc();
+ if(callback)
+ InsertUIntMapEntry(&TlsDestructor, *key, callback);
+ return 0;
+}
+
+int pthread_key_delete(pthread_key_t key)
+{
+ InsertUIntMapEntry(&TlsDestructor, key, NULL);
+ TlsFree(key);
+ return 0;
+}
+
+void *pthread_getspecific(pthread_key_t key)
+{ return TlsGetValue(key); }
+
+int pthread_setspecific(pthread_key_t key, void *val)
+{
+ TlsSetValue(key, val);
+ return 0;
+}
+
+
void *LoadLib(const char *name)
{ return LoadLibraryA(name); }
void CloseLib(void *handle)
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 0a006ee9..357090a6 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -160,6 +160,23 @@ typedef ptrdiff_t ALsizeiptrEXT;
#define RESTRICT
#endif
+
+typedef struct UIntMap {
+ struct {
+ ALuint key;
+ ALvoid *value;
+ } *array;
+ ALsizei size;
+ ALsizei maxsize;
+} UIntMap;
+
+void InitUIntMap(UIntMap *map);
+void ResetUIntMap(UIntMap *map);
+ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value);
+void RemoveUIntMapKey(UIntMap *map, ALuint key);
+ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key);
+
+
#ifdef _WIN32
#ifndef _WIN32_WINNT
@@ -167,11 +184,13 @@ typedef ptrdiff_t ALsizeiptrEXT;
#endif
#include <windows.h>
-typedef DWORD tls_type;
-#define tls_create(x) (*(x) = TlsAlloc())
-#define tls_delete(x) TlsFree((x))
-#define tls_get(x) TlsGetValue((x))
-#define tls_set(x, a) TlsSetValue((x), (a))
+extern UIntMap TlsDestructor;
+
+typedef DWORD pthread_key_t;
+int pthread_key_create(pthread_key_t *key, void (*callback)(void*));
+int pthread_key_delete(pthread_key_t key);
+void *pthread_getspecific(pthread_key_t key);
+int pthread_setspecific(pthread_key_t key, void *val);
#define HAVE_DYNLOAD 1
void *LoadLib(const char *name);
@@ -196,12 +215,6 @@ void pthread_once(pthread_once_t *once, void (*callback)(void));
#define IsBadWritePtr(a,b) ((a) == NULL && (b) != 0)
-typedef pthread_key_t tls_type;
-#define tls_create(x) pthread_key_create((x), NULL)
-#define tls_delete(x) pthread_key_delete((x))
-#define tls_get(x) pthread_getspecific((x))
-#define tls_set(x, a) pthread_setspecific((x), (a))
-
typedef pthread_mutex_t CRITICAL_SECTION;
void InitializeCriticalSection(CRITICAL_SECTION *cs);
void DeleteCriticalSection(CRITICAL_SECTION *cs);
@@ -365,21 +378,6 @@ void alc_loopback_deinit(void);
void alc_loopback_probe(enum DevProbe type);
-typedef struct UIntMap {
- struct {
- ALuint key;
- ALvoid *value;
- } *array;
- ALsizei size;
- ALsizei maxsize;
-} UIntMap;
-
-void InitUIntMap(UIntMap *map);
-void ResetUIntMap(UIntMap *map);
-ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value);
-void RemoveUIntMapKey(UIntMap *map, ALuint key);
-ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key);
-
/* Device formats */
enum DevFmtType {
DevFmtByte = AL_BYTE,