From 69cf1703567d1915059a8746376bd1829a7686b4 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 4 Oct 2016 06:46:46 -0700 Subject: [PATCH] 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 --- src/audio/SDL_audio.c | 14 ++++++++------ src/audio/alsa/SDL_alsa_audio.c | 4 +++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 29b08e732..f9cd73610 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -725,13 +725,15 @@ SDL_RunAudio(void *devicep) } /* !!! 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 6a5863fa5..2a3f3a39f 100644 --- a/src/audio/alsa/SDL_alsa_audio.c +++ b/src/audio/alsa/SDL_alsa_audio.c @@ -49,6 +49,7 @@ static snd_pcm_sframes_t (*ALSA_snd_pcm_readi) 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 @@ load_alsa_syms(void) 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 @@ static void 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);