From 494f3e66e4a04fbaa8ee6250e002d03e0800edad Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 15 Apr 2004 12:22:26 +0000 Subject: [PATCH] fixed the handling of EINTR in read/write. EINTR can be returned during ACPI suspend/resume. --- src/pcm/pcm.c | 4 ++-- src/pcm/pcm_hw.c | 8 ++++---- src/pcm/pcm_local.h | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 9befa900..1de19212 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -6066,7 +6066,7 @@ snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_ xfer += frames; } _end: - return xfer > 0 ? (snd_pcm_sframes_t) xfer : err; + return xfer > 0 ? (snd_pcm_sframes_t) xfer : snd_pcm_check_error(pcm, err); } snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas, @@ -6149,7 +6149,7 @@ snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area } } _end: - return xfer > 0 ? (snd_pcm_sframes_t) xfer : err; + return xfer > 0 ? (snd_pcm_sframes_t) xfer : snd_pcm_check_error(pcm, err); } snd_pcm_uframes_t _snd_pcm_mmap_hw_ptr(snd_pcm_t *pcm) diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index de269290..25395dbf 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -612,7 +612,7 @@ static snd_pcm_sframes_t snd_pcm_hw_writei(snd_pcm_t *pcm, const void *buffer, s fprintf(stderr, "hw_writei: frames = %li, result = %i, result = %li\n", size, result, xferi.result); #endif if (result < 0) - return err; + return snd_pcm_check_error(pcm, err); return xferi.result; } @@ -630,7 +630,7 @@ static snd_pcm_sframes_t snd_pcm_hw_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_ fprintf(stderr, "hw_writen: frames = %li, result = %i, result = %li\n", size, result, xfern.result); #endif if (result < 0) - return err; + return snd_pcm_check_error(pcm, err); return xfern.result; } @@ -648,7 +648,7 @@ static snd_pcm_sframes_t snd_pcm_hw_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_ fprintf(stderr, "hw_readi: frames = %li, result = %i, result = %li\n", size, result, xferi.result); #endif if (result < 0) - return err; + return snd_pcm_check_error(pcm, err); UPDATE_SHADOW_PTR(hw); return xferi.result; } @@ -667,7 +667,7 @@ static snd_pcm_sframes_t snd_pcm_hw_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_u fprintf(stderr, "hw_readn: frames = %li, result = %i, result = %li\n", size, result, xfern.result); #endif if (result < 0) - return err; + return snd_pcm_check_error(pcm, err); UPDATE_SHADOW_PTR(hw); return xfern.result; } diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 20c1784e..5693c82f 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -265,6 +265,22 @@ int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info); int snd_pcm_channel_info_shm(snd_pcm_t *pcm, snd_pcm_channel_info_t *info, int shmid); int _snd_pcm_poll_descriptor(snd_pcm_t *pcm); +/* handle special error cases */ +static inline int snd_pcm_check_error(snd_pcm_t *pcm, int err) +{ + if (err == -EINTR) { + switch (snd_pcm_state(pcm)) { + case SND_PCM_STATE_XRUN: + return -EPIPE; + case SND_PCM_STATE_SUSPENDED: + return -ESTRPIPE; + case SND_PCM_STATE_DISCONNECTED: + return -ENOTTY; + } + } + return err; +} + static inline snd_pcm_uframes_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm) { snd_pcm_sframes_t avail; -- 2.47.1