From da081b81c425805eef5b3d4a07c7a213490e04b7 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 29 Aug 2011 20:52:13 -0700 Subject: [PATCH] Do a compare-exchange to set the context error This allows for unlocked context access when getting the error --- OpenAL32/Include/alMain.h | 20 ++++++++++++++++++++ OpenAL32/alError.c | 7 +++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 9a7c1cc4..a0c83254 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -235,6 +235,10 @@ static __inline RefCount DecrementRef(volatile RefCount *ptr) static __inline T Exchange_##T(volatile T *ptr, T newval) \ { \ return __sync_lock_test_and_set(ptr, newval); \ +} \ +static __inline ALboolean CompExchange_##T(volatile T *ptr, T oldval, T newval)\ +{ \ + return __sync_bool_compare_and_swap(ptr, oldval, newval); \ } #elif defined(_WIN32) @@ -253,6 +257,14 @@ static __inline T Exchange_##T(volatile T *ptr, T newval) \ volatile LONG *l; \ } u = { ptr }; \ return InterlockedExchange(u.l, newval); \ +} \ +static __inline ALboolean CompExchange_##T(volatile T *ptr, T oldval, T newval)\ +{ \ + union { \ + volatile T *t; \ + volatile LONG *l; \ + } u = { ptr }; \ + return InterlockedCompareExchange(u.l, newval, oldval) == oldval; \ } #elif defined(__APPLE__) @@ -278,6 +290,14 @@ static __inline T Exchange_##T(volatile T *ptr, T newval) \ oldval = *u.i; \ } while(!OSAtomicCompareAndSwap32Barrier(oldval, newval, u.i)); \ return oldval; \ +} \ +static __inline ALboolean CompExchange_##T(volatile T *ptr, T oldval, T newval)\ +{ \ + union { \ + volatile T *t; \ + volatile int32_t *i; \ + } u = { ptr }; \ + return OSAtomicCompareAndSwap32Barrier(oldval, newval, u.i); \ } #else diff --git a/OpenAL32/alError.c b/OpenAL32/alError.c index b30755d9..edca01f2 100644 --- a/OpenAL32/alError.c +++ b/OpenAL32/alError.c @@ -29,18 +29,17 @@ AL_API ALenum AL_APIENTRY alGetError(ALvoid) ALCcontext *Context; ALenum errorCode; - Context = GetLockedContext(); + Context = GetReffedContext(); if(!Context) return AL_INVALID_OPERATION; errorCode = Exchange_ALenum(&Context->LastError, AL_NO_ERROR); - UnlockContext(Context); + ALCcontext_DecRef(Context); return errorCode; } ALvoid alSetError(ALCcontext *Context, ALenum errorCode) { - if(Context->LastError == AL_NO_ERROR) - Context->LastError = errorCode; + CompExchange_ALenum(&Context->LastError, AL_NO_ERROR, errorCode); }