aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
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 /Alc
parent82244f298ced5fd96dec5ee64c8a5b957b7dfdb4 (diff)
Emulate pthread TLS functions in Windows
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c40
-rw-r--r--Alc/helpers.c26
2 files changed, 54 insertions, 12 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)