diff options
author | Chris Robinson <[email protected]> | 2017-02-13 21:18:18 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2017-02-13 21:18:18 -0800 |
commit | 0d19a209014582f1e77ab3b927dfb1af6c307d66 (patch) | |
tree | 38d5b06d2003a23175522411bfeeffb8fc252f7a /Alc/ALu.c | |
parent | 0324712540f88d18f1fa8f18f7a72da06af00d75 (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/ALu.c')
-rw-r--r-- | Alc/ALu.c | 10 |
1 files changed, 6 insertions, 4 deletions
@@ -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); |