Do a compare-exchange to set the context error

This allows for unlocked context access when getting the error
This commit is contained in:
Chris Robinson 2011-08-29 20:52:13 -07:00
parent 500ad776ea
commit da081b81c4
2 changed files with 23 additions and 4 deletions

View File

@ -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

View File

@ -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);
}