audio: Made some SDL_AudioDevice fields atomic.
authorRyan C. Gordon <icculus@icculus.org>
Tue, 02 Aug 2016 13:48:52 -0400
changeset 102386fa358b97f4b
parent 10237 0d344873cd93
child 10239 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
     1.1 --- a/src/audio/SDL_audio.c	Tue Aug 02 13:38:56 2016 -0400
     1.2 +++ b/src/audio/SDL_audio.c	Tue Aug 02 13:48:52 2016 -0400
     1.3 @@ -366,14 +366,14 @@
     1.4  {
     1.5      SDL_assert(get_audio_device(device->id) == device);
     1.6  
     1.7 -    if (!device->enabled) {
     1.8 +    if (!SDL_AtomicGet(&device->enabled)) {
     1.9          return;
    1.10      }
    1.11  
    1.12      /* Ends the audio callback and mark the device as STOPPED, but the
    1.13         app still needs to close the device to free resources. */
    1.14      current_audio.impl.LockDevice(device);
    1.15 -    device->enabled = SDL_FALSE;
    1.16 +    SDL_AtomicSet(&device->enabled, 0);
    1.17      current_audio.impl.UnlockDevice(device);
    1.18  
    1.19      /* Post the event, if desired */
    1.20 @@ -615,7 +615,7 @@
    1.21          /* Fill the current buffer with sound */
    1.22          if (device->convert.needed) {
    1.23              stream = device->convert.buf;
    1.24 -        } else if (device->enabled) {
    1.25 +        } else if (SDL_AtomicGet(&device->enabled)) {
    1.26              stream = current_audio.impl.GetDeviceBuf(device);
    1.27          } else {
    1.28              /* if the device isn't enabled, we still write to the
    1.29 @@ -632,7 +632,7 @@
    1.30  
    1.31          /* !!! FIXME: this should be LockDevice. */
    1.32          SDL_LockMutex(device->mixer_lock);
    1.33 -        if (device->paused) {
    1.34 +        if (SDL_AtomicGet(&device->paused)) {
    1.35              SDL_memset(stream, silence, stream_len);
    1.36          } else {
    1.37              (*fill) (udata, stream, stream_len);
    1.38 @@ -640,7 +640,7 @@
    1.39          SDL_UnlockMutex(device->mixer_lock);
    1.40  
    1.41          /* Convert the audio if necessary */
    1.42 -        if (device->enabled && device->convert.needed) {
    1.43 +        if (device->convert.needed && SDL_AtomicGet(&device->enabled)) {
    1.44              SDL_ConvertAudio(&device->convert);
    1.45              stream = current_audio.impl.GetDeviceBuf(device);
    1.46              if (stream == NULL) {
    1.47 @@ -873,8 +873,8 @@
    1.48  static void
    1.49  close_audio_device(SDL_AudioDevice * device)
    1.50  {
    1.51 -    device->enabled = SDL_FALSE;
    1.52      SDL_AtomicSet(&device->shutdown, 1);
    1.53 +    SDL_AtomicSet(&device->enabled, 0);
    1.54      if (device->thread != NULL) {
    1.55          SDL_WaitThread(device->thread, NULL);
    1.56      }
    1.57 @@ -1074,13 +1074,14 @@
    1.58          return 0;
    1.59      }
    1.60      SDL_zerop(device);
    1.61 -    SDL_AtomicSet(&device->shutdown, 0);  /* just in case. */
    1.62      device->id = id + 1;
    1.63      device->spec = *obtained;
    1.64 -    device->enabled = SDL_TRUE;
    1.65 -    device->paused = SDL_TRUE;
    1.66      device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
    1.67  
    1.68 +    SDL_AtomicSet(&device->shutdown, 0);  /* just in case. */
    1.69 +    SDL_AtomicSet(&device->paused, 1);
    1.70 +    SDL_AtomicSet(&device->enabled, 1);
    1.71 +
    1.72      /* Create a mutex for locking the sound buffers */
    1.73      if (!current_audio.impl.SkipMixerLock) {
    1.74          device->mixer_lock = SDL_CreateMutex();
    1.75 @@ -1256,8 +1257,8 @@
    1.76  {
    1.77      SDL_AudioDevice *device = get_audio_device(devid);
    1.78      SDL_AudioStatus status = SDL_AUDIO_STOPPED;
    1.79 -    if (device && device->enabled) {
    1.80 -        if (device->paused) {
    1.81 +    if (device && SDL_AtomicGet(&device->enabled)) {
    1.82 +        if (SDL_AtomicGet(&device->paused)) {
    1.83              status = SDL_AUDIO_PAUSED;
    1.84          } else {
    1.85              status = SDL_AUDIO_PLAYING;
    1.86 @@ -1279,7 +1280,7 @@
    1.87      SDL_AudioDevice *device = get_audio_device(devid);
    1.88      if (device) {
    1.89          current_audio.impl.LockDevice(device);
    1.90 -        device->paused = pause_on ? SDL_TRUE : SDL_FALSE;
    1.91 +        SDL_AtomicSet(&device->paused, pause_on ? 1 : 0);
    1.92          current_audio.impl.UnlockDevice(device);
    1.93      }
    1.94  }
     2.1 --- a/src/audio/SDL_sysaudio.h	Tue Aug 02 13:38:56 2016 -0400
     2.2 +++ b/src/audio/SDL_sysaudio.h	Tue Aug 02 13:48:52 2016 -0400
     2.3 @@ -158,10 +158,10 @@
     2.4  
     2.5      /* Current state flags */
     2.6      SDL_atomic_t shutdown; /* true if we are signaling the play thread to end. */
     2.7 +    SDL_atomic_t enabled;  /* true if device is functioning and connected. */
     2.8 +    SDL_atomic_t paused;
     2.9 +    SDL_bool opened;
    2.10      SDL_bool iscapture;
    2.11 -    SDL_bool enabled;  /* true if device is functioning and connected. */
    2.12 -    SDL_bool paused;
    2.13 -    SDL_bool opened;
    2.14  
    2.15      /* Fake audio buffer for when the audio hardware is busy */
    2.16      Uint8 *fake_stream;
     3.1 --- a/src/audio/alsa/SDL_alsa_audio.c	Tue Aug 02 13:38:56 2016 -0400
     3.2 +++ b/src/audio/alsa/SDL_alsa_audio.c	Tue Aug 02 13:48:52 2016 -0400
     3.3 @@ -311,7 +311,7 @@
     3.4  
     3.5      swizzle_alsa_channels(this);
     3.6  
     3.7 -    while ( frames_left > 0 && this->enabled ) {
     3.8 +    while ( frames_left > 0 && SDL_AtomicGet(&this->enabled) ) {
     3.9          /* !!! FIXME: This works, but needs more testing before going live */
    3.10          /* ALSA_snd_pcm_wait(this->hidden->pcm_handle, -1); */
    3.11          status = ALSA_snd_pcm_writei(this->hidden->pcm_handle,
     4.1 --- a/src/audio/android/SDL_androidaudio.c	Tue Aug 02 13:38:56 2016 -0400
     4.2 +++ b/src/audio/android/SDL_androidaudio.c	Tue Aug 02 13:48:52 2016 -0400
     4.3 @@ -151,13 +151,13 @@
     4.4      struct SDL_PrivateAudioData *private;
     4.5      if(audioDevice != NULL && audioDevice->hidden != NULL) {
     4.6          private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
     4.7 -        if (audioDevice->paused) {
     4.8 +        if (SDL_AtomicGet(&audioDevice->paused)) {
     4.9              /* The device is already paused, leave it alone */
    4.10              private->resume = SDL_FALSE;
    4.11          }
    4.12          else {
    4.13              SDL_LockMutex(audioDevice->mixer_lock);
    4.14 -            audioDevice->paused = SDL_TRUE;
    4.15 +            SDL_AtomicSet(&audioDevice->paused, 1);
    4.16              private->resume = SDL_TRUE;
    4.17          }
    4.18      }
    4.19 @@ -171,7 +171,7 @@
    4.20      if(audioDevice != NULL && audioDevice->hidden != NULL) {
    4.21          private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
    4.22          if (private->resume) {
    4.23 -            audioDevice->paused = SDL_FALSE;
    4.24 +            SDL_AtomicSet(&audioDevice->paused, 0);
    4.25              private->resume = SDL_FALSE;
    4.26              SDL_UnlockMutex(audioDevice->mixer_lock);
    4.27          }
     5.1 --- a/src/audio/coreaudio/SDL_coreaudio.c	Tue Aug 02 13:38:56 2016 -0400
     5.2 +++ b/src/audio/coreaudio/SDL_coreaudio.c	Tue Aug 02 13:48:52 2016 -0400
     5.3 @@ -283,7 +283,7 @@
     5.4      UInt32 i;
     5.5  
     5.6      /* Only do anything if audio is enabled and not paused */
     5.7 -    if (!this->enabled || this->paused) {
     5.8 +    if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
     5.9          for (i = 0; i < ioData->mNumberBuffers; i++) {
    5.10              abuf = &ioData->mBuffers[i];
    5.11              SDL_memset(abuf->mData, this->spec.silence, abuf->mDataByteSize);
    5.12 @@ -335,7 +335,7 @@
    5.13                AudioBufferList *ioData)
    5.14  {
    5.15      SDL_AudioDevice *this = (SDL_AudioDevice *) inRefCon;
    5.16 -    if (!this->enabled || this->paused) {
    5.17 +    if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
    5.18          return noErr;  /* just drop this if we're not accepting input. */
    5.19      }
    5.20  
    5.21 @@ -391,7 +391,7 @@
    5.22      UInt32 size = sizeof (isAlive);
    5.23      OSStatus error;
    5.24  
    5.25 -    if (!this->enabled) {
    5.26 +    if (!SDL_AtomicGet(&this->enabled)) {
    5.27          return 0;  /* already known to be dead. */
    5.28      }
    5.29  
     6.1 --- a/src/audio/emscripten/SDL_emscriptenaudio.c	Tue Aug 02 13:38:56 2016 -0400
     6.2 +++ b/src/audio/emscripten/SDL_emscriptenaudio.c	Tue Aug 02 13:48:52 2016 -0400
     6.3 @@ -63,12 +63,10 @@
     6.4      int bytes = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
     6.5      int bytes_in = SDL_AUDIO_BITSIZE(this->convert.src_format) / 8;
     6.6  
     6.7 -    /* Only do soemthing if audio is enabled */
     6.8 -    if (!this->enabled)
     6.9 +    /* Only do something if audio is enabled */
    6.10 +    if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
    6.11          return;
    6.12 -
    6.13 -    if (this->paused)
    6.14 -        return;
    6.15 +    }
    6.16  
    6.17      if (this->convert.needed) {
    6.18          if (this->hidden->conv_in_len != 0) {
     7.1 --- a/src/audio/haiku/SDL_haikuaudio.cc	Tue Aug 02 13:38:56 2016 -0400
     7.2 +++ b/src/audio/haiku/SDL_haikuaudio.cc	Tue Aug 02 13:48:52 2016 -0400
     7.3 @@ -49,10 +49,11 @@
     7.4      SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
     7.5  
     7.6      /* Only do soemthing if audio is enabled */
     7.7 -    if (!audio->enabled)
     7.8 +    if (!SDL_AtomicGet(&audio->enabled)) {
     7.9          return;
    7.10 +    }
    7.11  
    7.12 -    if (!audio->paused) {
    7.13 +    if (!SDL_AtomicGet(&audio->paused)) {
    7.14          if (audio->convert.needed) {
    7.15              SDL_LockMutex(audio->mixer_lock);
    7.16              (*audio->spec.callback) (audio->spec.userdata,
     8.1 --- a/src/audio/nacl/SDL_naclaudio.c	Tue Aug 02 13:38:56 2016 -0400
     8.2 +++ b/src/audio/nacl/SDL_naclaudio.c	Tue Aug 02 13:48:52 2016 -0400
     8.3 @@ -53,7 +53,7 @@
     8.4      
     8.5      SDL_LockMutex(private->mutex);  /* !!! FIXME: is this mutex necessary? */
     8.6  
     8.7 -    if (_this->enabled && !_this->paused) {
     8.8 +    if (SDL_AtomicGet(&this->enabled) && !SDL_AtomicGet(&this->paused)) {
     8.9          if (_this->convert.needed) {
    8.10              SDL_LockMutex(_this->mixer_lock);
    8.11              (*_this->spec.callback) (_this->spec.userdata,
     9.1 --- a/src/audio/pulseaudio/SDL_pulseaudio.c	Tue Aug 02 13:38:56 2016 -0400
     9.2 +++ b/src/audio/pulseaudio/SDL_pulseaudio.c	Tue Aug 02 13:48:52 2016 -0400
     9.3 @@ -326,7 +326,7 @@
     9.4  {
     9.5      struct SDL_PrivateAudioData *h = this->hidden;
     9.6  
     9.7 -    while (this->enabled) {
     9.8 +    while (SDL_AtomicGet(&this->enabled)) {
     9.9          if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
    9.10              PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
    9.11              PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
    9.12 @@ -344,7 +344,7 @@
    9.13  {
    9.14      /* Write the audio data */
    9.15      struct SDL_PrivateAudioData *h = this->hidden;
    9.16 -    if (this->enabled) {
    9.17 +    if (SDL_AtomicGet(&this->enabled)) {
    9.18          if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
    9.19              SDL_OpenedAudioDeviceDisconnected(this);
    9.20          }
    9.21 @@ -360,7 +360,7 @@
    9.22  static void
    9.23  PULSEAUDIO_WaitDone(_THIS)
    9.24  {
    9.25 -    if (this->enabled) {
    9.26 +    if (SDL_AtomicGet(&this->enabled)) {
    9.27          struct SDL_PrivateAudioData *h = this->hidden;
    9.28          pa_operation *o = PULSEAUDIO_pa_stream_drain(h->stream, stream_drain_complete, NULL);
    9.29          if (o) {
    10.1 --- a/src/audio/qsa/SDL_qsa_audio.c	Tue Aug 02 13:38:56 2016 -0400
    10.2 +++ b/src/audio/qsa/SDL_qsa_audio.c	Tue Aug 02 13:48:52 2016 -0400
    10.3 @@ -229,7 +229,7 @@
    10.4      int towrite;
    10.5      void *pcmbuffer;
    10.6  
    10.7 -    if ((!this->enabled) || (!this->hidden)) {
    10.8 +    if (!SDL_AtomicGet(&this->enabled) || !this->hidden) {
    10.9          return;
   10.10      }
   10.11  
   10.12 @@ -305,7 +305,7 @@
   10.13              towrite -= written;
   10.14              pcmbuffer += written * this->spec.channels;
   10.15          }
   10.16 -    } while ((towrite > 0) && (this->enabled));
   10.17 +    } while ((towrite > 0) && SDL_AtomicGet(&this->enabled));
   10.18  
   10.19      /* If we couldn't write, assume fatal error for now */
   10.20      if (towrite != 0) {
    11.1 --- a/src/audio/xaudio2/SDL_xaudio2.c	Tue Aug 02 13:38:56 2016 -0400
    11.2 +++ b/src/audio/xaudio2/SDL_xaudio2.c	Tue Aug 02 13:48:52 2016 -0400
    11.3 @@ -195,7 +195,7 @@
    11.4      IXAudio2SourceVoice *source = this->hidden->source;
    11.5      HRESULT result = S_OK;
    11.6  
    11.7 -    if (!this->enabled) { /* shutting down? */
    11.8 +    if (!SDL_AtomicGet(&this->enabled)) { /* shutting down? */
    11.9          return;
   11.10      }
   11.11  
   11.12 @@ -226,7 +226,7 @@
   11.13  static void
   11.14  XAUDIO2_WaitDevice(_THIS)
   11.15  {
   11.16 -    if (this->enabled) {
   11.17 +    if (SDL_AtomicGet(&this->enabled)) {
   11.18          SDL_SemWait(this->hidden->semaphore);
   11.19      }
   11.20  }
   11.21 @@ -236,7 +236,7 @@
   11.22  {
   11.23      IXAudio2SourceVoice *source = this->hidden->source;
   11.24      XAUDIO2_VOICE_STATE state;
   11.25 -    SDL_assert(!this->enabled);  /* flag that stops playing. */
   11.26 +    SDL_assert(!SDL_AtomicGet(&this->enabled));  /* flag that stops playing. */
   11.27      IXAudio2SourceVoice_Discontinuity(source);
   11.28  #if SDL_XAUDIO2_WIN8
   11.29      IXAudio2SourceVoice_GetState(source, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED);