audio: Made some SDL_AudioDevice fields atomic.
authorRyan C. Gordon <icculus@icculus.org>
Tue, 02 Aug 2016 13:48:52 -0400
changeset 10220 6fa358b97f4b
parent 10219 0d344873cd93
child 10221 04cda108b406
audio: Made some SDL_AudioDevice fields atomic. This makes sure they're properly communicated to the audio threads.
src/audio/SDL_audio.c
src/audio/SDL_sysaudio.h
src/audio/alsa/SDL_alsa_audio.c
src/audio/android/SDL_androidaudio.c
src/audio/coreaudio/SDL_coreaudio.c
src/audio/emscripten/SDL_emscriptenaudio.c
src/audio/haiku/SDL_haikuaudio.cc
src/audio/nacl/SDL_naclaudio.c
src/audio/pulseaudio/SDL_pulseaudio.c
src/audio/qsa/SDL_qsa_audio.c
src/audio/xaudio2/SDL_xaudio2.c
--- a/src/audio/SDL_audio.c	Tue Aug 02 13:38:56 2016 -0400
+++ b/src/audio/SDL_audio.c	Tue Aug 02 13:48:52 2016 -0400
@@ -366,14 +366,14 @@
 {
     SDL_assert(get_audio_device(device->id) == device);
 
-    if (!device->enabled) {
+    if (!SDL_AtomicGet(&device->enabled)) {
         return;
     }
 
     /* Ends the audio callback and mark the device as STOPPED, but the
        app still needs to close the device to free resources. */
     current_audio.impl.LockDevice(device);
-    device->enabled = SDL_FALSE;
+    SDL_AtomicSet(&device->enabled, 0);
     current_audio.impl.UnlockDevice(device);
 
     /* Post the event, if desired */
@@ -615,7 +615,7 @@
         /* Fill the current buffer with sound */
         if (device->convert.needed) {
             stream = device->convert.buf;
-        } else if (device->enabled) {
+        } else if (SDL_AtomicGet(&device->enabled)) {
             stream = current_audio.impl.GetDeviceBuf(device);
         } else {
             /* if the device isn't enabled, we still write to the
@@ -632,7 +632,7 @@
 
         /* !!! FIXME: this should be LockDevice. */
         SDL_LockMutex(device->mixer_lock);
-        if (device->paused) {
+        if (SDL_AtomicGet(&device->paused)) {
             SDL_memset(stream, silence, stream_len);
         } else {
             (*fill) (udata, stream, stream_len);
@@ -640,7 +640,7 @@
         SDL_UnlockMutex(device->mixer_lock);
 
         /* Convert the audio if necessary */
-        if (device->enabled && device->convert.needed) {
+        if (device->convert.needed && SDL_AtomicGet(&device->enabled)) {
             SDL_ConvertAudio(&device->convert);
             stream = current_audio.impl.GetDeviceBuf(device);
             if (stream == NULL) {
@@ -873,8 +873,8 @@
 static void
 close_audio_device(SDL_AudioDevice * device)
 {
-    device->enabled = SDL_FALSE;
     SDL_AtomicSet(&device->shutdown, 1);
+    SDL_AtomicSet(&device->enabled, 0);
     if (device->thread != NULL) {
         SDL_WaitThread(device->thread, NULL);
     }
@@ -1074,13 +1074,14 @@
         return 0;
     }
     SDL_zerop(device);
-    SDL_AtomicSet(&device->shutdown, 0);  /* just in case. */
     device->id = id + 1;
     device->spec = *obtained;
-    device->enabled = SDL_TRUE;
-    device->paused = SDL_TRUE;
     device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
 
+    SDL_AtomicSet(&device->shutdown, 0);  /* just in case. */
+    SDL_AtomicSet(&device->paused, 1);
+    SDL_AtomicSet(&device->enabled, 1);
+
     /* Create a mutex for locking the sound buffers */
     if (!current_audio.impl.SkipMixerLock) {
         device->mixer_lock = SDL_CreateMutex();
@@ -1256,8 +1257,8 @@
 {
     SDL_AudioDevice *device = get_audio_device(devid);
     SDL_AudioStatus status = SDL_AUDIO_STOPPED;
-    if (device && device->enabled) {
-        if (device->paused) {
+    if (device && SDL_AtomicGet(&device->enabled)) {
+        if (SDL_AtomicGet(&device->paused)) {
             status = SDL_AUDIO_PAUSED;
         } else {
             status = SDL_AUDIO_PLAYING;
@@ -1279,7 +1280,7 @@
     SDL_AudioDevice *device = get_audio_device(devid);
     if (device) {
         current_audio.impl.LockDevice(device);
-        device->paused = pause_on ? SDL_TRUE : SDL_FALSE;
+        SDL_AtomicSet(&device->paused, pause_on ? 1 : 0);
         current_audio.impl.UnlockDevice(device);
     }
 }
--- a/src/audio/SDL_sysaudio.h	Tue Aug 02 13:38:56 2016 -0400
+++ b/src/audio/SDL_sysaudio.h	Tue Aug 02 13:48:52 2016 -0400
@@ -158,10 +158,10 @@
 
     /* Current state flags */
     SDL_atomic_t shutdown; /* true if we are signaling the play thread to end. */
+    SDL_atomic_t enabled;  /* true if device is functioning and connected. */
+    SDL_atomic_t paused;
+    SDL_bool opened;
     SDL_bool iscapture;
-    SDL_bool enabled;  /* true if device is functioning and connected. */
-    SDL_bool paused;
-    SDL_bool opened;
 
     /* Fake audio buffer for when the audio hardware is busy */
     Uint8 *fake_stream;
--- a/src/audio/alsa/SDL_alsa_audio.c	Tue Aug 02 13:38:56 2016 -0400
+++ b/src/audio/alsa/SDL_alsa_audio.c	Tue Aug 02 13:48:52 2016 -0400
@@ -311,7 +311,7 @@
 
     swizzle_alsa_channels(this);
 
-    while ( frames_left > 0 && this->enabled ) {
+    while ( frames_left > 0 && SDL_AtomicGet(&this->enabled) ) {
         /* !!! FIXME: This works, but needs more testing before going live */
         /* ALSA_snd_pcm_wait(this->hidden->pcm_handle, -1); */
         status = ALSA_snd_pcm_writei(this->hidden->pcm_handle,
--- a/src/audio/android/SDL_androidaudio.c	Tue Aug 02 13:38:56 2016 -0400
+++ b/src/audio/android/SDL_androidaudio.c	Tue Aug 02 13:48:52 2016 -0400
@@ -151,13 +151,13 @@
     struct SDL_PrivateAudioData *private;
     if(audioDevice != NULL && audioDevice->hidden != NULL) {
         private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
-        if (audioDevice->paused) {
+        if (SDL_AtomicGet(&audioDevice->paused)) {
             /* The device is already paused, leave it alone */
             private->resume = SDL_FALSE;
         }
         else {
             SDL_LockMutex(audioDevice->mixer_lock);
-            audioDevice->paused = SDL_TRUE;
+            SDL_AtomicSet(&audioDevice->paused, 1);
             private->resume = SDL_TRUE;
         }
     }
@@ -171,7 +171,7 @@
     if(audioDevice != NULL && audioDevice->hidden != NULL) {
         private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
         if (private->resume) {
-            audioDevice->paused = SDL_FALSE;
+            SDL_AtomicSet(&audioDevice->paused, 0);
             private->resume = SDL_FALSE;
             SDL_UnlockMutex(audioDevice->mixer_lock);
         }
--- a/src/audio/coreaudio/SDL_coreaudio.c	Tue Aug 02 13:38:56 2016 -0400
+++ b/src/audio/coreaudio/SDL_coreaudio.c	Tue Aug 02 13:48:52 2016 -0400
@@ -283,7 +283,7 @@
     UInt32 i;
 
     /* Only do anything if audio is enabled and not paused */
-    if (!this->enabled || this->paused) {
+    if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
         for (i = 0; i < ioData->mNumberBuffers; i++) {
             abuf = &ioData->mBuffers[i];
             SDL_memset(abuf->mData, this->spec.silence, abuf->mDataByteSize);
@@ -335,7 +335,7 @@
               AudioBufferList *ioData)
 {
     SDL_AudioDevice *this = (SDL_AudioDevice *) inRefCon;
-    if (!this->enabled || this->paused) {
+    if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
         return noErr;  /* just drop this if we're not accepting input. */
     }
 
@@ -391,7 +391,7 @@
     UInt32 size = sizeof (isAlive);
     OSStatus error;
 
-    if (!this->enabled) {
+    if (!SDL_AtomicGet(&this->enabled)) {
         return 0;  /* already known to be dead. */
     }
 
--- a/src/audio/emscripten/SDL_emscriptenaudio.c	Tue Aug 02 13:38:56 2016 -0400
+++ b/src/audio/emscripten/SDL_emscriptenaudio.c	Tue Aug 02 13:48:52 2016 -0400
@@ -63,12 +63,10 @@
     int bytes = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
     int bytes_in = SDL_AUDIO_BITSIZE(this->convert.src_format) / 8;
 
-    /* Only do soemthing if audio is enabled */
-    if (!this->enabled)
+    /* Only do something if audio is enabled */
+    if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
         return;
-
-    if (this->paused)
-        return;
+    }
 
     if (this->convert.needed) {
         if (this->hidden->conv_in_len != 0) {
--- a/src/audio/haiku/SDL_haikuaudio.cc	Tue Aug 02 13:38:56 2016 -0400
+++ b/src/audio/haiku/SDL_haikuaudio.cc	Tue Aug 02 13:48:52 2016 -0400
@@ -49,10 +49,11 @@
     SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
 
     /* Only do soemthing if audio is enabled */
-    if (!audio->enabled)
+    if (!SDL_AtomicGet(&audio->enabled)) {
         return;
+    }
 
-    if (!audio->paused) {
+    if (!SDL_AtomicGet(&audio->paused)) {
         if (audio->convert.needed) {
             SDL_LockMutex(audio->mixer_lock);
             (*audio->spec.callback) (audio->spec.userdata,
--- a/src/audio/nacl/SDL_naclaudio.c	Tue Aug 02 13:38:56 2016 -0400
+++ b/src/audio/nacl/SDL_naclaudio.c	Tue Aug 02 13:48:52 2016 -0400
@@ -53,7 +53,7 @@
     
     SDL_LockMutex(private->mutex);  /* !!! FIXME: is this mutex necessary? */
 
-    if (_this->enabled && !_this->paused) {
+    if (SDL_AtomicGet(&this->enabled) && !SDL_AtomicGet(&this->paused)) {
         if (_this->convert.needed) {
             SDL_LockMutex(_this->mixer_lock);
             (*_this->spec.callback) (_this->spec.userdata,
--- a/src/audio/pulseaudio/SDL_pulseaudio.c	Tue Aug 02 13:38:56 2016 -0400
+++ b/src/audio/pulseaudio/SDL_pulseaudio.c	Tue Aug 02 13:48:52 2016 -0400
@@ -326,7 +326,7 @@
 {
     struct SDL_PrivateAudioData *h = this->hidden;
 
-    while (this->enabled) {
+    while (SDL_AtomicGet(&this->enabled)) {
         if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
             PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
             PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
@@ -344,7 +344,7 @@
 {
     /* Write the audio data */
     struct SDL_PrivateAudioData *h = this->hidden;
-    if (this->enabled) {
+    if (SDL_AtomicGet(&this->enabled)) {
         if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
             SDL_OpenedAudioDeviceDisconnected(this);
         }
@@ -360,7 +360,7 @@
 static void
 PULSEAUDIO_WaitDone(_THIS)
 {
-    if (this->enabled) {
+    if (SDL_AtomicGet(&this->enabled)) {
         struct SDL_PrivateAudioData *h = this->hidden;
         pa_operation *o = PULSEAUDIO_pa_stream_drain(h->stream, stream_drain_complete, NULL);
         if (o) {
--- a/src/audio/qsa/SDL_qsa_audio.c	Tue Aug 02 13:38:56 2016 -0400
+++ b/src/audio/qsa/SDL_qsa_audio.c	Tue Aug 02 13:48:52 2016 -0400
@@ -229,7 +229,7 @@
     int towrite;
     void *pcmbuffer;
 
-    if ((!this->enabled) || (!this->hidden)) {
+    if (!SDL_AtomicGet(&this->enabled) || !this->hidden) {
         return;
     }
 
@@ -305,7 +305,7 @@
             towrite -= written;
             pcmbuffer += written * this->spec.channels;
         }
-    } while ((towrite > 0) && (this->enabled));
+    } while ((towrite > 0) && SDL_AtomicGet(&this->enabled));
 
     /* If we couldn't write, assume fatal error for now */
     if (towrite != 0) {
--- a/src/audio/xaudio2/SDL_xaudio2.c	Tue Aug 02 13:38:56 2016 -0400
+++ b/src/audio/xaudio2/SDL_xaudio2.c	Tue Aug 02 13:48:52 2016 -0400
@@ -195,7 +195,7 @@
     IXAudio2SourceVoice *source = this->hidden->source;
     HRESULT result = S_OK;
 
-    if (!this->enabled) { /* shutting down? */
+    if (!SDL_AtomicGet(&this->enabled)) { /* shutting down? */
         return;
     }
 
@@ -226,7 +226,7 @@
 static void
 XAUDIO2_WaitDevice(_THIS)
 {
-    if (this->enabled) {
+    if (SDL_AtomicGet(&this->enabled)) {
         SDL_SemWait(this->hidden->semaphore);
     }
 }
@@ -236,7 +236,7 @@
 {
     IXAudio2SourceVoice *source = this->hidden->source;
     XAUDIO2_VOICE_STATE state;
-    SDL_assert(!this->enabled);  /* flag that stops playing. */
+    SDL_assert(!SDL_AtomicGet(&this->enabled));  /* flag that stops playing. */
     IXAudio2SourceVoice_Discontinuity(source);
 #if SDL_XAUDIO2_WIN8
     IXAudio2SourceVoice_GetState(source, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED);