From ba65ef5ce7bba8a7cf7b639fe63aba990c403ce0 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 28 Sep 2023 20:16:59 -0700 Subject: [PATCH] Recover from -EPIPE in snd_pcm_avail() --- src/audio/alsa/SDL_alsa_audio.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c index a8b9abfa93..0d63213b36 100644 --- a/src/audio/alsa/SDL_alsa_audio.c +++ b/src/audio/alsa/SDL_alsa_audio.c @@ -336,11 +336,16 @@ static void ALSA_WaitDevice(SDL_AudioDevice *device) const snd_pcm_sframes_t needed = (snd_pcm_sframes_t)device->sample_frames; while (!SDL_AtomicGet(&device->shutdown)) { const snd_pcm_sframes_t rc = ALSA_snd_pcm_avail(device->hidden->pcm_handle); - if ((rc < 0) && (rc != -EAGAIN)) { - /* Hmm, not much we can do - abort */ - fprintf(stderr, "ALSA snd_pcm_avail failed (unrecoverable): %s\n", - ALSA_snd_strerror(rc)); - SDL_AudioDeviceDisconnected(device); + if (rc < 0 && rc != -EAGAIN) { + int status = rc; + + status = ALSA_snd_pcm_recover(device->hidden->pcm_handle, status, 0); + if (status < 0) { + /* Hmm, not much we can do - abort */ + fprintf(stderr, "ALSA snd_pcm_avail failed (unrecoverable): %s\n", + ALSA_snd_strerror(rc)); + SDL_AudioDeviceDisconnected(device); + } return; } else if (rc < needed) { const Uint32 delay = ((needed - (SDL_max(rc, 0))) * 1000) / device->spec.freq; @@ -363,7 +368,6 @@ static int ALSA_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buf while ((frames_left > 0) && !SDL_AtomicGet(&device->shutdown)) { int status = ALSA_snd_pcm_writei(device->hidden->pcm_handle, sample_buf, frames_left); - if (status < 0) { if (status == -EAGAIN) { /* Apparently snd_pcm_recover() doesn't handle this case -