diff options
-rw-r--r-- | Alc/alc.cpp | 41 | ||||
-rw-r--r-- | Alc/backends/base.h | 6 | ||||
-rw-r--r-- | OpenAL32/alSource.cpp | 42 |
3 files changed, 34 insertions, 55 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp index 59582ea6..b69c4756 100644 --- a/Alc/alc.cpp +++ b/Alc/alc.cpp @@ -2494,9 +2494,6 @@ ALCcontext_struct::~ALCcontext_struct() */ static bool ReleaseContext(ALCcontext *context, ALCdevice *device) { - ALCcontext *origctx, *newhead; - bool ret = true; - if(LocalContext.get() == context) { WARN("%p released while current on thread\n", context); @@ -2504,27 +2501,28 @@ static bool ReleaseContext(ALCcontext *context, ALCdevice *device) ALCcontext_DecRef(context); } - origctx = context; + ALCcontext *origctx{context}; if(GlobalContext.compare_exchange_strong(origctx, nullptr)) ALCcontext_DecRef(context); - device->Backend->lock(); - origctx = context; - newhead = context->next.load(std::memory_order_relaxed); - if(!device->ContextList.compare_exchange_strong(origctx, newhead)) - { - ALCcontext *list; - do { - /* origctx is what the desired context failed to match. Try - * swapping out the next one in the list. - */ - list = origctx; - origctx = context; - } while(!list->next.compare_exchange_strong(origctx, newhead)); + bool ret{true}; + { BackendLockGuard _{*device->Backend}; + origctx = context; + ALCcontext *newhead{context->next.load(std::memory_order_relaxed)}; + if(!device->ContextList.compare_exchange_strong(origctx, newhead)) + { + ALCcontext *list; + do { + /* origctx is what the desired context failed to match. Try + * swapping out the next one in the list. + */ + list = origctx; + origctx = context; + } while(!list->next.compare_exchange_strong(origctx, newhead)); + } + else + ret = !!newhead; } - else - ret = !!newhead; - device->Backend->unlock(); /* Make sure the context is finished and no longer processing in the mixer * before sending the message queue kill event. The backend's lock does @@ -4146,9 +4144,8 @@ FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, AL alcSetError(dev.get(), ALC_INVALID_VALUE); else { - dev->Backend->lock(); + BackendLockGuard _{*device->Backend}; aluMixData(dev.get(), buffer, samples); - dev->Backend->unlock(); } } diff --git a/Alc/backends/base.h b/Alc/backends/base.h index fc50af2b..93685d5a 100644 --- a/Alc/backends/base.h +++ b/Alc/backends/base.h @@ -41,8 +41,8 @@ struct BackendBase { virtual ClockLatency getClockLatency(); - virtual void lock() { mMutex.lock(); }; - virtual void unlock() { mMutex.unlock(); }; + virtual void lock() { mMutex.lock(); } + virtual void unlock() { mMutex.unlock(); } ALCdevice *mDevice; @@ -52,6 +52,8 @@ struct BackendBase { virtual ~BackendBase(); }; using BackendPtr = std::unique_ptr<BackendBase>; +using BackendUniqueLock = std::unique_lock<BackendBase>; +using BackendLockGuard = std::lock_guard<BackendBase>; enum class BackendType { Playback, diff --git a/OpenAL32/alSource.cpp b/OpenAL32/alSource.cpp index a3428e02..5ce14bbf 100644 --- a/OpenAL32/alSource.cpp +++ b/OpenAL32/alSource.cpp @@ -526,14 +526,13 @@ void FreeSource(ALCcontext *context, ALsource *source) ALsizei slidx = id & 0x3f; ALCdevice *device{context->Device}; - device->Backend->lock(); - ALvoice *voice{GetSourceVoice(source, context)}; - if(voice) + BackendUniqueLock backlock{*device->Backend}; + if(ALvoice *voice{GetSourceVoice(source, context)}) { voice->SourceID.store(0u, std::memory_order_relaxed); voice->Playing.store(false, std::memory_order_release); } - device->Backend->unlock(); + backlock.unlock(); source->~ALsource(); @@ -1095,21 +1094,15 @@ ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, co if(IsPlayingOrPaused(Source)) { ALCdevice *device{Context->Device}; - - device->Backend->lock(); + BackendLockGuard _{*device->Backend}; /* Double-check that the source is still playing while we have * the lock. */ - ALvoice *voice{GetSourceVoice(Source, Context)}; - if(voice) + if(ALvoice *voice{GetSourceVoice(Source, Context)}) { if(ApplyOffset(Source, voice) == AL_FALSE) - { - device->Backend->unlock(); SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid offset"); - } } - device->Backend->unlock(); } return AL_TRUE; @@ -1322,18 +1315,13 @@ ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, co if(IsPlayingOrPaused(Source)) { ALCdevice *device{Context->Device}; - device->Backend->lock(); - ALvoice *voice{GetSourceVoice(Source, Context)}; - if(voice) + BackendLockGuard _{*device->Backend}; + if(ALvoice *voice{GetSourceVoice(Source, Context)}) { if(ApplyOffset(Source, voice) == AL_FALSE) - { - device->Backend->unlock(); SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid source offset"); - } } - device->Backend->unlock(); } return AL_TRUE; @@ -2705,7 +2693,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) SETERR_RETURN(context.get(), AL_INVALID_NAME,, "Invalid source ID %u", *bad_sid); ALCdevice *device{context->Device}; - device->Backend->lock(); + BackendLockGuard __{*device->Backend}; /* If the device is disconnected, go right to stopped. */ if(UNLIKELY(!device->Connected.load(std::memory_order_acquire))) { @@ -2719,18 +2707,14 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) source->state = AL_STOPPED; } ); - device->Backend->unlock(); return; } while(n > context->MaxVoices-context->VoiceCount.load(std::memory_order_relaxed)) { if(UNLIKELY(context->MaxVoices > std::numeric_limits<ALsizei>::max()>>1)) - { - device->Backend->unlock(); SETERR_RETURN(context.get(), AL_OUT_OF_MEMORY,, "Overflow increasing voice count from %d", context->MaxVoices); - } ALsizei newcount = context->MaxVoices << 1; AllocateVoices(context.get(), newcount, device->NumAuxSends); } @@ -2862,7 +2846,6 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) SendStateChangeEvent(context.get(), source->id, AL_PLAYING); }; std::for_each(sources, sources_end, start_source); - device->Backend->unlock(); } AL_API ALvoid AL_APIENTRY alSourcePause(ALuint source) @@ -2886,7 +2869,7 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) } ALCdevice *device{context->Device}; - device->Backend->lock(); + BackendLockGuard __{*device->Backend}; for(ALsizei i{0};i < n;i++) { ALsource *source{LookupSource(context.get(), sources[i])}; @@ -2898,7 +2881,6 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) SendStateChangeEvent(context.get(), source->id, AL_PAUSED); } } - device->Backend->unlock(); } AL_API ALvoid AL_APIENTRY alSourceStop(ALuint source) @@ -2922,7 +2904,7 @@ AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) } ALCdevice *device{context->Device}; - device->Backend->lock(); + BackendLockGuard __{*device->Backend}; for(ALsizei i{0};i < n;i++) { ALsource *source{LookupSource(context.get(), sources[i])}; @@ -2942,7 +2924,6 @@ AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) source->OffsetType = AL_NONE; source->Offset = 0.0; } - device->Backend->unlock(); } AL_API ALvoid AL_APIENTRY alSourceRewind(ALuint source) @@ -2966,7 +2947,7 @@ AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) } ALCdevice *device{context->Device}; - device->Backend->lock(); + BackendLockGuard __{*device->Backend}; for(ALsizei i{0};i < n;i++) { ALsource *source{LookupSource(context.get(), sources[i])}; @@ -2985,7 +2966,6 @@ AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) source->OffsetType = AL_NONE; source->Offset = 0.0; } - device->Backend->unlock(); } |