aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-02-13 21:18:18 -0800
committerChris Robinson <[email protected]>2017-02-13 21:18:18 -0800
commit0d19a209014582f1e77ab3b927dfb1af6c307d66 (patch)
tree38d5b06d2003a23175522411bfeeffb8fc252f7a /Alc
parent0324712540f88d18f1fa8f18f7a72da06af00d75 (diff)
Make the source state atomic
Since it's modified by the mixer when playback is ended, a plain struct member isn't safe.
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c3
-rw-r--r--Alc/ALu.c10
-rw-r--r--Alc/mixer.c2
3 files changed, 8 insertions, 7 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index fcc6d649..69e37540 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1697,8 +1697,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context)
ALsource *Source = context->SourceMap.values[pos];
ALenum new_state;
- if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
- Source->OffsetType != AL_NONE)
+ if(Source->OffsetType != AL_NONE && IsPlayingOrPaused(Source))
{
WriteLock(&Source->queue_lock);
ApplyOffset(Source);
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 42f229a2..31dd6271 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -1326,7 +1326,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot)
for(;voice != voice_end;++voice)
{
if(!(source=voice->Source)) continue;
- if(source->state != AL_PLAYING && source->state != AL_PAUSED)
+ if(!IsPlayingOrPaused(source))
voice->Source = NULL;
else
CalcSourceParams(voice, ctx, force);
@@ -1449,7 +1449,8 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
{
ALboolean IsVoiceInit = (voice->Step > 0);
source = voice->Source;
- if(source && source->state == AL_PLAYING && IsVoiceInit)
+ if(IsVoiceInit && source &&
+ ATOMIC_LOAD(&source->state, almemory_order_relaxed) == AL_PLAYING)
MixSource(voice, source, device, SamplesToDo);
}
@@ -1614,12 +1615,13 @@ void aluHandleDisconnect(ALCdevice *device)
voice_end = voice + Context->VoiceCount;
while(voice != voice_end)
{
+ ALenum playing = AL_PLAYING;
ALsource *source = voice->Source;
voice->Source = NULL;
- if(source && source->state == AL_PLAYING)
+ if(source &&
+ ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &source->state, &playing, AL_STOPPED))
{
- source->state = AL_STOPPED;
ATOMIC_STORE(&source->current_buffer, NULL, almemory_order_relaxed);
ATOMIC_STORE(&source->position, 0, almemory_order_relaxed);
ATOMIC_STORE(&source->position_fraction, 0, almemory_order_release);
diff --git a/Alc/mixer.c b/Alc/mixer.c
index 592d51d4..179c028e 100644
--- a/Alc/mixer.c
+++ b/Alc/mixer.c
@@ -711,7 +711,7 @@ void MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei Samp
voice->Moving = AL_TRUE;
/* Update source info */
- Source->state = State;
+ ATOMIC_STORE(&Source->state, State, almemory_order_relaxed);
ATOMIC_STORE(&Source->current_buffer, BufferListItem, almemory_order_relaxed);
ATOMIC_STORE(&Source->position, DataPosInt, almemory_order_relaxed);
ATOMIC_STORE(&Source->position_fraction, DataPosFrac, almemory_order_release);