diff options
author | Chris Robinson <[email protected]> | 2022-04-24 23:25:49 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2022-04-25 17:32:20 -0700 |
commit | 2daed0d0b4e264c97dc0491e5d7fc6847cd1289d (patch) | |
tree | ccd5ffc61642a02a4d8464770b7fb157697b4f24 /alc/alu.cpp | |
parent | 31d7d62eea535decb968845d6ca7698f1a92997c (diff) |
Fully protect disconnection with the mixer counter
Diffstat (limited to 'alc/alu.cpp')
-rw-r--r-- | alc/alu.cpp | 72 |
1 files changed, 36 insertions, 36 deletions
diff --git a/alc/alu.cpp b/alc/alu.cpp index b75735f3..0ba83739 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -2004,50 +2004,50 @@ void DeviceBase::renderSamples(void *outBuffer, const uint numSamples, const siz void DeviceBase::handleDisconnect(const char *msg, ...) { - if(!Connected.exchange(false, std::memory_order_acq_rel)) - return; - - AsyncEvent evt{AsyncEvent::Disconnected}; + IncrementRef(MixCount); + if(Connected.exchange(false, std::memory_order_acq_rel)) + { + AsyncEvent evt{AsyncEvent::Disconnected}; - va_list args; - va_start(args, msg); - int msglen{vsnprintf(evt.u.disconnect.msg, sizeof(evt.u.disconnect.msg), msg, args)}; - va_end(args); + va_list args; + va_start(args, msg); + int msglen{vsnprintf(evt.u.disconnect.msg, sizeof(evt.u.disconnect.msg), msg, args)}; + va_end(args); - if(msglen < 0 || static_cast<size_t>(msglen) >= sizeof(evt.u.disconnect.msg)) - evt.u.disconnect.msg[sizeof(evt.u.disconnect.msg)-1] = 0; + if(msglen < 0 || static_cast<size_t>(msglen) >= sizeof(evt.u.disconnect.msg)) + evt.u.disconnect.msg[sizeof(evt.u.disconnect.msg)-1] = 0; - IncrementRef(MixCount); - for(ContextBase *ctx : *mContexts.load()) - { - const uint enabledevt{ctx->mEnabledEvts.load(std::memory_order_acquire)}; - if((enabledevt&AsyncEvent::Disconnected)) + for(ContextBase *ctx : *mContexts.load()) { - RingBuffer *ring{ctx->mAsyncEvents.get()}; - auto evt_data = ring->getWriteVector().first; - if(evt_data.len > 0) + const uint enabledevt{ctx->mEnabledEvts.load(std::memory_order_acquire)}; + if((enabledevt&AsyncEvent::Disconnected)) { - al::construct_at(reinterpret_cast<AsyncEvent*>(evt_data.buf), evt); - ring->writeAdvance(1); - ctx->mEventSem.post(); + RingBuffer *ring{ctx->mAsyncEvents.get()}; + auto evt_data = ring->getWriteVector().first; + if(evt_data.len > 0) + { + al::construct_at(reinterpret_cast<AsyncEvent*>(evt_data.buf), evt); + ring->writeAdvance(1); + ctx->mEventSem.post(); + } } - } - if(!ctx->mStopVoicesOnDisconnect) - { - ProcessVoiceChanges(ctx); - continue; - } + if(!ctx->mStopVoicesOnDisconnect) + { + ProcessVoiceChanges(ctx); + continue; + } - auto voicelist = ctx->getVoicesSpanAcquired(); - auto stop_voice = [](Voice *voice) -> void - { - voice->mCurrentBuffer.store(nullptr, std::memory_order_relaxed); - voice->mLoopBuffer.store(nullptr, std::memory_order_relaxed); - voice->mSourceID.store(0u, std::memory_order_relaxed); - voice->mPlayState.store(Voice::Stopped, std::memory_order_release); - }; - std::for_each(voicelist.begin(), voicelist.end(), stop_voice); + auto voicelist = ctx->getVoicesSpanAcquired(); + auto stop_voice = [](Voice *voice) -> void + { + voice->mCurrentBuffer.store(nullptr, std::memory_order_relaxed); + voice->mLoopBuffer.store(nullptr, std::memory_order_relaxed); + voice->mSourceID.store(0u, std::memory_order_relaxed); + voice->mPlayState.store(Voice::Stopped, std::memory_order_release); + }; + std::for_each(voicelist.begin(), voicelist.end(), stop_voice); + } } IncrementRef(MixCount); } |