diff options
author | Chris Robinson <[email protected]> | 2011-08-28 17:21:01 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2011-08-28 17:21:01 -0700 |
commit | 5eceb593e9cfd57611e99217e2f9c346bb10305c (patch) | |
tree | e24bef2ea66470eabd8c8f2dfe19c8e38e7dc45a | |
parent | 82244f298ced5fd96dec5ee64c8a5b957b7dfdb4 (diff) |
Emulate pthread TLS functions in Windows
-rw-r--r-- | Alc/ALc.c | 40 | ||||
-rw-r--r-- | Alc/helpers.c | 26 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 50 |
3 files changed, 78 insertions, 38 deletions
@@ -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, |