diff options
author | Chris Robinson <[email protected]> | 2014-05-11 03:52:22 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2014-05-11 03:52:22 -0700 |
commit | b89cc3417b5c0396082b5fe0d5175bf625f0d3c4 (patch) | |
tree | 6de00899dc40cfca47f8ad8279e5b414c3d26da6 /OpenAL32 | |
parent | 9f8615c670e251cd8b2a513d11e156bcd0dea6d9 (diff) |
Avoid locking the mixer when unqueueing buffers
Diffstat (limited to 'OpenAL32')
-rw-r--r-- | OpenAL32/alSource.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index d707f226..f0fb374f 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -33,6 +33,8 @@ #include "alThunk.h" #include "alAuxEffectSlot.h" +#include "threads.h" + enum Resampler DefaultResampler = LinearResampler; const ALsizei ResamplerPadding[ResamplerMax] = { @@ -2223,10 +2225,20 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint OldHead = ExchangePtr((XchgPtr*)&source->queue, BufferList); if(BufferList) { - LockContext(context); - BufferList->prev->next = NULL; - BufferList->prev = NULL; - UnlockContext(context); + ALCdevice *device = context->Device; + RefCount count; + + /* Cut the new head's link back to the old body. The mixer is robust + * enough to handle the link back going away. Once the active mix (if + * any) is complete, it's safe to finish cutting the old tail from the + * new head. */ + BufferList = ExchangePtr((XchgPtr*)&BufferList->prev, NULL); + if(((count=device->MixCount)&1) != 0) + { + while(count == device->MixCount) + althrd_yield(); + } + BufferList->next = NULL; } WriteUnlock(&source->queue_lock); |