diff options
author | Chris Robinson <[email protected]> | 2016-05-11 18:40:17 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2016-05-11 21:02:11 -0700 |
commit | 186b54aa3d5f1398a384fa318aa000210d82437e (patch) | |
tree | 32daef17365aee1fb61a05db9b6c23aec25f6e07 /OpenAL32/alState.c | |
parent | 21bc0f5ef8f0e410ea840061589b844d6e401afc (diff) |
Use a lockless method for updating listener and context properties
This uses a separate container to provide the relevant properties to the
internal update method, using atomic pointer swaps. A free-list is used to
avoid having too many individual containers.
This allows the mixer to update the internal listener properties without
requiring the lock to protect against async updates. It also allows concurrent
read access to the user-facing property values, even the multi-value ones (e.g.
the vectors).
Diffstat (limited to 'OpenAL32/alState.c')
-rw-r--r-- | OpenAL32/alState.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index dca41363..899dacd4 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -26,6 +26,7 @@ #include "AL/al.h" #include "AL/alext.h" #include "alError.h" +#include "alListener.h" #include "alSource.h" #include "alAuxEffectSlot.h" @@ -55,12 +56,15 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability) { case AL_SOURCE_DISTANCE_MODEL: context->SourceDistanceModel = AL_TRUE; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + /* HACK: Force sources to update by doing a listener update */ + ReadLock(&context->PropLock); + UpdateListenerProps(context); + ReadUnlock(&context->PropLock); done: ALCcontext_DecRef(context); @@ -77,12 +81,15 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability) { case AL_SOURCE_DISTANCE_MODEL: context->SourceDistanceModel = AL_FALSE; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + /* HACK: Force sources to update by doing a listener update */ + ReadLock(&context->PropLock); + UpdateListenerProps(context); + ReadUnlock(&context->PropLock); done: ALCcontext_DecRef(context); @@ -547,8 +554,10 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value) if(!(value >= 0.0f && isfinite(value))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + WriteLock(&context->PropLock); context->DopplerFactor = value; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); + UpdateListenerProps(context); + WriteUnlock(&context->PropLock); done: ALCcontext_DecRef(context); @@ -564,8 +573,10 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value) if(!(value >= 0.0f && isfinite(value))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + WriteLock(&context->PropLock); context->DopplerVelocity = value; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); + UpdateListenerProps(context); + WriteUnlock(&context->PropLock); done: ALCcontext_DecRef(context); @@ -581,8 +592,10 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value) if(!(value > 0.0f && isfinite(value))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + WriteLock(&context->PropLock); context->SpeedOfSound = value; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); + UpdateListenerProps(context); + WriteUnlock(&context->PropLock); done: ALCcontext_DecRef(context); @@ -601,9 +614,11 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value) value == AL_NONE)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + WriteLock(&context->PropLock); context->DistanceModel = value; if(!context->SourceDistanceModel) - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); + UpdateListenerProps(context); + WriteUnlock(&context->PropLock); done: ALCcontext_DecRef(context); |