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
This commit is contained in:
Sam Lantinga 2016-10-04 06:46:46 -07:00
parent 2558c9c836
commit 69cf170356
2 changed files with 11 additions and 7 deletions

View File

@ -725,13 +725,15 @@ SDL_RunAudio(void *devicep)
} }
/* !!! FIXME: this should be LockDevice. */ /* !!! FIXME: this should be LockDevice. */
SDL_LockMutex(device->mixer_lock); if ( SDL_AtomicGet(&device->enabled) ) {
if (SDL_AtomicGet(&device->paused)) { SDL_LockMutex(device->mixer_lock);
SDL_memset(stream, silence, stream_len); if (SDL_AtomicGet(&device->paused)) {
} else { SDL_memset(stream, silence, stream_len);
(*callback) (udata, stream, stream_len); } else {
(*callback) (udata, stream, stream_len);
}
SDL_UnlockMutex(device->mixer_lock);
} }
SDL_UnlockMutex(device->mixer_lock);
/* Convert the audio if necessary */ /* Convert the audio if necessary */
if (device->convert.needed && SDL_AtomicGet(&device->enabled)) { if (device->convert.needed && SDL_AtomicGet(&device->enabled)) {

View File

@ -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_recover) (snd_pcm_t *, int, int);
static int (*ALSA_snd_pcm_prepare) (snd_pcm_t *); static int (*ALSA_snd_pcm_prepare) (snd_pcm_t *);
static int (*ALSA_snd_pcm_drain) (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 const char *(*ALSA_snd_strerror) (int);
static size_t(*ALSA_snd_pcm_hw_params_sizeof) (void); static size_t(*ALSA_snd_pcm_hw_params_sizeof) (void);
static size_t(*ALSA_snd_pcm_sw_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_recover);
SDL_ALSA_SYM(snd_pcm_prepare); SDL_ALSA_SYM(snd_pcm_prepare);
SDL_ALSA_SYM(snd_pcm_drain); SDL_ALSA_SYM(snd_pcm_drain);
SDL_ALSA_SYM(snd_pcm_drop);
SDL_ALSA_SYM(snd_strerror); SDL_ALSA_SYM(snd_strerror);
SDL_ALSA_SYM(snd_pcm_hw_params_sizeof); SDL_ALSA_SYM(snd_pcm_hw_params_sizeof);
SDL_ALSA_SYM(snd_pcm_sw_params_sizeof); SDL_ALSA_SYM(snd_pcm_sw_params_sizeof);
@ -402,7 +404,7 @@ static void
ALSA_CloseDevice(_THIS) ALSA_CloseDevice(_THIS)
{ {
if (this->hidden->pcm_handle) { 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); ALSA_snd_pcm_close(this->hidden->pcm_handle);
} }
SDL_free(this->hidden->mixbuf); SDL_free(this->hidden->mixbuf);