fix deadlock on close device
James Zipperer
snd_pcm_drain doesn't always drain when you unplug a usb device. Use snd_pcm_drop instead
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index 29b08e7..f9cd736 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -725,13 +725,15 @@
}
/* !!! FIXME: this should be LockDevice. */
- SDL_LockMutex(device->mixer_lock);
- if (SDL_AtomicGet(&device->paused)) {
- SDL_memset(stream, silence, stream_len);
- } else {
- (*callback) (udata, stream, stream_len);
+ if ( SDL_AtomicGet(&device->enabled) ) {
+ SDL_LockMutex(device->mixer_lock);
+ if (SDL_AtomicGet(&device->paused)) {
+ SDL_memset(stream, silence, stream_len);
+ } else {
+ (*callback) (udata, stream, stream_len);
+ }
+ SDL_UnlockMutex(device->mixer_lock);
}
- SDL_UnlockMutex(device->mixer_lock);
/* Convert the audio if necessary */
if (device->convert.needed && SDL_AtomicGet(&device->enabled)) {
diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c
index 6a5863f..2a3f3a3 100644
--- a/src/audio/alsa/SDL_alsa_audio.c
+++ b/src/audio/alsa/SDL_alsa_audio.c
@@ -49,6 +49,7 @@
static int (*ALSA_snd_pcm_recover) (snd_pcm_t *, int, int);
static int (*ALSA_snd_pcm_prepare) (snd_pcm_t *);
static int (*ALSA_snd_pcm_drain) (snd_pcm_t *);
+static int (*ALSA_snd_pcm_drop) (snd_pcm_t *);
static const char *(*ALSA_snd_strerror) (int);
static size_t(*ALSA_snd_pcm_hw_params_sizeof) (void);
static size_t(*ALSA_snd_pcm_sw_params_sizeof) (void);
@@ -128,6 +129,7 @@
SDL_ALSA_SYM(snd_pcm_recover);
SDL_ALSA_SYM(snd_pcm_prepare);
SDL_ALSA_SYM(snd_pcm_drain);
+ SDL_ALSA_SYM(snd_pcm_drop);
SDL_ALSA_SYM(snd_strerror);
SDL_ALSA_SYM(snd_pcm_hw_params_sizeof);
SDL_ALSA_SYM(snd_pcm_sw_params_sizeof);
@@ -402,7 +404,7 @@
ALSA_CloseDevice(_THIS)
{
if (this->hidden->pcm_handle) {
- ALSA_snd_pcm_drain(this->hidden->pcm_handle);
+ ALSA_snd_pcm_drop(this->hidden->pcm_handle);
ALSA_snd_pcm_close(this->hidden->pcm_handle);
}
SDL_free(this->hidden->mixbuf);