Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
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
- Loading branch information
Showing
with
11 additions
and
7 deletions.
-
+8
−6
src/audio/SDL_audio.c
-
+3
−1
src/audio/alsa/SDL_alsa_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)) { |
|
|
|
@@ -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); |
|
|