Emulate pthread TLS functions in Windows
This commit is contained in:
parent
82244f298c
commit
5eceb593e9
40
Alc/ALc.c
40
Alc/ALc.c
@ -367,7 +367,7 @@ static ALCcontext *g_pContextList = NULL;
|
|||||||
static ALCuint g_ulContextCount = 0;
|
static ALCuint g_ulContextCount = 0;
|
||||||
|
|
||||||
// Thread-local current context
|
// Thread-local current context
|
||||||
static tls_type LocalContext;
|
static pthread_key_t LocalContext;
|
||||||
// Process-wide current context
|
// Process-wide current context
|
||||||
static ALCcontext *GlobalContext;
|
static ALCcontext *GlobalContext;
|
||||||
|
|
||||||
@ -421,21 +421,37 @@ static void alc_deinit(void);
|
|||||||
static void alc_deinit_safe(void);
|
static void alc_deinit_safe(void);
|
||||||
|
|
||||||
#ifndef AL_LIBTYPE_STATIC
|
#ifndef AL_LIBTYPE_STATIC
|
||||||
|
UIntMap TlsDestructor;
|
||||||
|
|
||||||
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
|
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
|
||||||
{
|
{
|
||||||
|
ALsizei i;
|
||||||
|
(void)hModule;
|
||||||
|
|
||||||
// Perform actions based on the reason for calling.
|
// Perform actions based on the reason for calling.
|
||||||
switch(ul_reason_for_call)
|
switch(ul_reason_for_call)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
DisableThreadLibraryCalls(hModule);
|
InitUIntMap(&TlsDestructor);
|
||||||
alc_init();
|
alc_init();
|
||||||
break;
|
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:
|
case DLL_PROCESS_DETACH:
|
||||||
if(!lpReserved)
|
if(!lpReserved)
|
||||||
alc_deinit();
|
alc_deinit();
|
||||||
else
|
else
|
||||||
alc_deinit_safe();
|
alc_deinit_safe();
|
||||||
|
ResetUIntMap(&TlsDestructor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -483,7 +499,7 @@ static void alc_init(void)
|
|||||||
if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
|
if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
|
||||||
ZScale = -1.0;
|
ZScale = -1.0;
|
||||||
|
|
||||||
tls_create(&LocalContext);
|
pthread_key_create(&LocalContext, NULL);
|
||||||
InitializeCriticalSection(&ListLock);
|
InitializeCriticalSection(&ListLock);
|
||||||
ThunkInit();
|
ThunkInit();
|
||||||
}
|
}
|
||||||
@ -496,7 +512,7 @@ static void alc_deinit_safe(void)
|
|||||||
|
|
||||||
ThunkExit();
|
ThunkExit();
|
||||||
DeleteCriticalSection(&ListLock);
|
DeleteCriticalSection(&ListLock);
|
||||||
tls_delete(LocalContext);
|
pthread_key_delete(LocalContext);
|
||||||
|
|
||||||
if(LogFile != stderr)
|
if(LogFile != stderr)
|
||||||
fclose(LogFile);
|
fclose(LogFile);
|
||||||
@ -1295,10 +1311,10 @@ ALCcontext *GetLockedContext(void)
|
|||||||
|
|
||||||
LockLists();
|
LockLists();
|
||||||
|
|
||||||
pContext = tls_get(LocalContext);
|
pContext = pthread_getspecific(LocalContext);
|
||||||
if(pContext && !IsContext(pContext))
|
if(pContext && !IsContext(pContext))
|
||||||
{
|
{
|
||||||
tls_set(LocalContext, NULL);
|
pthread_setspecific(LocalContext, NULL);
|
||||||
pContext = NULL;
|
pContext = NULL;
|
||||||
}
|
}
|
||||||
if(!pContext)
|
if(!pContext)
|
||||||
@ -2125,10 +2141,10 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(ALCvoid)
|
|||||||
ALCcontext *Context;
|
ALCcontext *Context;
|
||||||
|
|
||||||
LockLists();
|
LockLists();
|
||||||
Context = tls_get(LocalContext);
|
Context = pthread_getspecific(LocalContext);
|
||||||
if(Context && !IsContext(Context))
|
if(Context && !IsContext(Context))
|
||||||
{
|
{
|
||||||
tls_set(LocalContext, NULL);
|
pthread_setspecific(LocalContext, NULL);
|
||||||
Context = NULL;
|
Context = NULL;
|
||||||
}
|
}
|
||||||
if(!Context)
|
if(!Context)
|
||||||
@ -2149,10 +2165,10 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
|
|||||||
|
|
||||||
LockLists();
|
LockLists();
|
||||||
|
|
||||||
pContext = tls_get(LocalContext);
|
pContext = pthread_getspecific(LocalContext);
|
||||||
if(pContext && !IsContext(pContext))
|
if(pContext && !IsContext(pContext))
|
||||||
{
|
{
|
||||||
tls_set(LocalContext, NULL);
|
pthread_setspecific(LocalContext, NULL);
|
||||||
pContext = NULL;
|
pContext = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2197,7 +2213,7 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
|
|||||||
if(context == NULL || IsContext(context))
|
if(context == NULL || IsContext(context))
|
||||||
{
|
{
|
||||||
GlobalContext = context;
|
GlobalContext = context;
|
||||||
tls_set(LocalContext, NULL);
|
pthread_setspecific(LocalContext, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2223,7 +2239,7 @@ ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
|
|||||||
|
|
||||||
// context must be a valid Context or NULL
|
// context must be a valid Context or NULL
|
||||||
if(context == NULL || IsContext(context))
|
if(context == NULL || IsContext(context))
|
||||||
tls_set(LocalContext, context);
|
pthread_setspecific(LocalContext, context);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
alcSetError(NULL, ALC_INVALID_CONTEXT);
|
alcSetError(NULL, ALC_INVALID_CONTEXT);
|
||||||
|
@ -59,6 +59,32 @@ void pthread_once(pthread_once_t *once, void (*callback)(void))
|
|||||||
InterlockedExchange(once, 2);
|
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)
|
void *LoadLib(const char *name)
|
||||||
{ return LoadLibraryA(name); }
|
{ return LoadLibraryA(name); }
|
||||||
void CloseLib(void *handle)
|
void CloseLib(void *handle)
|
||||||
|
@ -160,6 +160,23 @@ typedef ptrdiff_t ALsizeiptrEXT;
|
|||||||
#define RESTRICT
|
#define RESTRICT
|
||||||
#endif
|
#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
|
#ifdef _WIN32
|
||||||
|
|
||||||
#ifndef _WIN32_WINNT
|
#ifndef _WIN32_WINNT
|
||||||
@ -167,11 +184,13 @@ typedef ptrdiff_t ALsizeiptrEXT;
|
|||||||
#endif
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
typedef DWORD tls_type;
|
extern UIntMap TlsDestructor;
|
||||||
#define tls_create(x) (*(x) = TlsAlloc())
|
|
||||||
#define tls_delete(x) TlsFree((x))
|
typedef DWORD pthread_key_t;
|
||||||
#define tls_get(x) TlsGetValue((x))
|
int pthread_key_create(pthread_key_t *key, void (*callback)(void*));
|
||||||
#define tls_set(x, a) TlsSetValue((x), (a))
|
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
|
#define HAVE_DYNLOAD 1
|
||||||
void *LoadLib(const char *name);
|
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)
|
#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;
|
typedef pthread_mutex_t CRITICAL_SECTION;
|
||||||
void InitializeCriticalSection(CRITICAL_SECTION *cs);
|
void InitializeCriticalSection(CRITICAL_SECTION *cs);
|
||||||
void DeleteCriticalSection(CRITICAL_SECTION *cs);
|
void DeleteCriticalSection(CRITICAL_SECTION *cs);
|
||||||
@ -365,21 +378,6 @@ void alc_loopback_deinit(void);
|
|||||||
void alc_loopback_probe(enum DevProbe type);
|
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 */
|
/* Device formats */
|
||||||
enum DevFmtType {
|
enum DevFmtType {
|
||||||
DevFmtByte = AL_BYTE,
|
DevFmtByte = AL_BYTE,
|
||||||
|
Loading…
Reference in New Issue
Block a user