summaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2011-08-28 18:08:48 -0700
committerChris Robinson <[email protected]>2011-08-28 18:08:48 -0700
commitf8c4b16c30743088e0ab9fd7219432a12983fafa (patch)
treefb18c1de2332ccbc6033897eb2f0846c7d2764c3 /Alc
parentc567339718b10713a695bcb9cd171919779780a4 (diff)
Hold a reference on the context when being set as current on the thread
This should vastly improve efficiency for retrieving the current thread context, as we can be assured the stored context pointer will always be valid.
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c90
1 files changed, 50 insertions, 40 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index ac169eac..0bdd61f5 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -411,6 +411,7 @@ static pthread_once_t alc_config_once = PTHREAD_ONCE_INIT;
///////////////////////////////////////////////////////
// ALC Related helper functions
static void ReleaseALC(ALCboolean doclose);
+static void ReleaseThreadCtx(void *ptr);
static void alc_initconfig(void);
#define DO_INITCONFIG() pthread_once(&alc_config_once, alc_initconfig)
@@ -499,7 +500,7 @@ static void alc_init(void)
if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
ZScale = -1.0;
- pthread_key_create(&LocalContext, NULL);
+ pthread_key_create(&LocalContext, ReleaseThreadCtx);
InitializeCriticalSection(&ListLock);
ThunkInit();
}
@@ -1307,24 +1308,21 @@ ALCvoid UnlockContext(ALCcontext *context)
*/
ALCcontext *GetLockedContext(void)
{
- ALCcontext *pContext = NULL;
+ ALCcontext *context = NULL;
- LockLists();
-
- pContext = pthread_getspecific(LocalContext);
- if(pContext && !IsContext(pContext))
+ context = pthread_getspecific(LocalContext);
+ if(context)
+ LockContext(context);
+ else
{
- pthread_setspecific(LocalContext, NULL);
- pContext = NULL;
+ LockLists();
+ context = GlobalContext;
+ if(context)
+ LockContext(context);
+ UnlockLists();
}
- if(!pContext)
- pContext = GlobalContext;
- if(pContext)
- LockContext(pContext);
- UnlockLists();
-
- return pContext;
+ return context;
}
@@ -1406,10 +1404,24 @@ static ALCvoid FreeContext(ALCcontext *context)
free(context);
}
+static void ALCcontext_IncRef(ALCcontext *context)
+{
+ RefCount ref;
+ ref = IncrementRef(&context->ref);
+ TRACE("%p refcount increment to %d\n", context, ref);
+}
+
static void ALCcontext_DecRef(ALCcontext *context)
{
- if(DecrementRef(&context->ref) == 0)
- FreeContext(context);
+ RefCount ref;
+ ref = DecrementRef(&context->ref);
+ TRACE("%p refcount decrement to %d\n", context, ref);
+ if(ref == 0) FreeContext(context);
+}
+
+static void ReleaseThreadCtx(void *ptr)
+{
+ ALCcontext_DecRef(ptr);
}
///////////////////////////////////////////////////////
@@ -2140,16 +2152,13 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(ALCvoid)
{
ALCcontext *Context;
- LockLists();
Context = pthread_getspecific(LocalContext);
- if(Context && !IsContext(Context))
- {
- pthread_setspecific(LocalContext, NULL);
- Context = NULL;
- }
if(!Context)
+ {
+ LockLists();
Context = GlobalContext;
- UnlockLists();
+ UnlockLists();
+ }
return Context;
}
@@ -2161,20 +2170,9 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(ALCvoid)
*/
ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
{
- ALCcontext *pContext = NULL;
-
- LockLists();
-
- pContext = pthread_getspecific(LocalContext);
- if(pContext && !IsContext(pContext))
- {
- pthread_setspecific(LocalContext, NULL);
- pContext = NULL;
- }
-
- UnlockLists();
-
- return pContext;
+ ALCcontext *Context;
+ Context = pthread_getspecific(LocalContext);
+ return Context;
}
@@ -2213,7 +2211,11 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
if(context == NULL || IsContext(context))
{
GlobalContext = context;
- pthread_setspecific(LocalContext, NULL);
+ if((context=pthread_getspecific(LocalContext)) != NULL)
+ {
+ pthread_setspecific(LocalContext, NULL);
+ ALCcontext_DecRef(context);
+ }
}
else
{
@@ -2239,7 +2241,15 @@ ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
// context must be a valid Context or NULL
if(context == NULL || IsContext(context))
- pthread_setspecific(LocalContext, context);
+ {
+ ALCcontext *old = pthread_getspecific(LocalContext);
+ if(old != context)
+ {
+ if(context) ALCcontext_IncRef(context);
+ pthread_setspecific(LocalContext, context);
+ if(old) ALCcontext_DecRef(old);
+ }
+ }
else
{
alcSetError(NULL, ALC_INVALID_CONTEXT);