diff options
-rw-r--r-- | include/control.h | 2 | ||||
-rw-r--r-- | include/pcm.h | 3 | ||||
-rw-r--r-- | src/control/control.c | 2 | ||||
-rw-r--r-- | src/control/control_local.h | 2 | ||||
-rw-r--r-- | src/control/hcontrol.c | 2 | ||||
-rw-r--r-- | src/pcm/pcm.c | 8 | ||||
-rw-r--r-- | src/pcm/pcm_local.h | 2 |
7 files changed, 17 insertions, 4 deletions
diff --git a/include/control.h b/include/control.h index e8408355..27fe2ac8 100644 --- a/include/control.h +++ b/include/control.h @@ -234,6 +234,7 @@ int snd_ctl_open_lconf(snd_ctl_t **ctl, const char *name, int mode, snd_config_t int snd_ctl_open_fallback(snd_ctl_t **ctl, snd_config_t *root, const char *name, const char *orig_name, int mode); int snd_ctl_close(snd_ctl_t *ctl); int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock); +static inline int snd_ctl_abort(snd_ctl_t *ctl) { return snd_ctl_nonblock(ctl, 2); } int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl, snd_async_callback_t callback, void *private_data); snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler); @@ -531,6 +532,7 @@ int snd_hctl_open(snd_hctl_t **hctl, const char *name, int mode); int snd_hctl_open_ctl(snd_hctl_t **hctlp, snd_ctl_t *ctl); int snd_hctl_close(snd_hctl_t *hctl); int snd_hctl_nonblock(snd_hctl_t *hctl, int nonblock); +static inline int snd_hctl_abort(snd_hctl_t *hctl) { return snd_hctl_nonblock(hctl, 2); } int snd_hctl_poll_descriptors_count(snd_hctl_t *hctl); int snd_hctl_poll_descriptors(snd_hctl_t *hctl, struct pollfd *pfds, unsigned int space); int snd_hctl_poll_descriptors_revents(snd_hctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); diff --git a/include/pcm.h b/include/pcm.h index 22356784..549d6292 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -314,6 +314,8 @@ typedef long snd_pcm_sframes_t; #define SND_PCM_NONBLOCK 0x00000001 /** Async notification (flag for open mode) \hideinitializer */ #define SND_PCM_ASYNC 0x00000002 +/** In an abort state (internal, not allowed for open) */ +#define SND_PCM_ABORT 0x00008000 /** Disable automatic (but not forced!) rate resamplinig */ #define SND_PCM_NO_AUTO_RESAMPLE 0x00010000 /** Disable automatic (but not forced!) channel conversion */ @@ -437,6 +439,7 @@ int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm); int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space); int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock); +static inline int snd_pcm_abort(snd_pcm_t *pcm) { return snd_pcm_nonblock(pcm, 2); } int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm, snd_async_callback_t callback, void *private_data); snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler); diff --git a/src/control/control.c b/src/control/control.c index 66277efe..5687ce14 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -103,7 +103,7 @@ int snd_ctl_close(snd_ctl_t *ctl) /** * \brief set nonblock mode * \param ctl CTL handle - * \param nonblock 0 = block, 1 = nonblock mode + * \param nonblock 0 = block, 1 = nonblock mode, 2 = abort * \return 0 on success otherwise a negative error code */ int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock) diff --git a/src/control/control_local.h b/src/control/control_local.h index 49150d8d..9594ae51 100644 --- a/src/control/control_local.h +++ b/src/control/control_local.h @@ -98,3 +98,5 @@ int _snd_ctl_poll_descriptor(snd_ctl_t *ctl); int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card, int mode); int snd_ctl_shm_open(snd_ctl_t **handlep, const char *name, const char *sockname, const char *sname, int mode); int snd_ctl_async(snd_ctl_t *ctl, int sig, pid_t pid); + +#define CTLINABORT(x) ((x)->nonblock == 2) diff --git a/src/control/hcontrol.c b/src/control/hcontrol.c index ee1d9079..7645c573 100644 --- a/src/control/hcontrol.c +++ b/src/control/hcontrol.c @@ -696,7 +696,7 @@ int snd_hctl_wait(snd_hctl_t *hctl, int timeout) pollio = 0; err_poll = poll(pfd, npfds, timeout); if (err_poll < 0) { - if (errno == EINTR) + if (errno == EINTR && !CTLINABORT(hctl->ctl)) continue; return -errno; } diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 0868dd58..38febb9d 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -716,7 +716,7 @@ int snd_pcm_close(snd_pcm_t *pcm) /** * \brief set nonblock mode * \param pcm PCM handle - * \param nonblock 0 = block, 1 = nonblock mode + * \param nonblock 0 = block, 1 = nonblock mode, 2 = abort * \return 0 on success otherwise a negative error code */ int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock) @@ -725,6 +725,10 @@ int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock) assert(pcm); if ((err = pcm->ops->nonblock(pcm->op_arg, nonblock)) < 0) return err; + if (nonblock == 2) { + pcm->mode |= SND_PCM_ABORT; + return 0; + } if (nonblock) pcm->mode |= SND_PCM_NONBLOCK; else { @@ -2401,7 +2405,7 @@ int snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout) do { err_poll = poll(pfd, npfds, timeout); if (err_poll < 0) { - if (errno == EINTR) + if (errno == EINTR && !PCMINABORT(pcm)) continue; return -errno; } diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 63b9036f..e1c0baa8 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -1006,3 +1006,5 @@ static inline void sw_set_period_event(snd_pcm_sw_params_t *params, int val) { params->reserved[sizeof(params->reserved) / sizeof(params->reserved[0]) - 1] = val; } + +#define PCMINABORT(pcm) (((pcm)->mode & SND_PCM_ABORT) != 0) |