aboutsummaryrefslogtreecommitdiffstats
path: root/alc/alu.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2022-04-24 23:25:49 -0700
committerChris Robinson <[email protected]>2022-04-25 17:32:20 -0700
commit2daed0d0b4e264c97dc0491e5d7fc6847cd1289d (patch)
treeccd5ffc61642a02a4d8464770b7fb157697b4f24 /alc/alu.cpp
parent31d7d62eea535decb968845d6ca7698f1a92997c (diff)
Fully protect disconnection with the mixer counter
Diffstat (limited to 'alc/alu.cpp')
-rw-r--r--alc/alu.cpp72
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);
}