mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
control, pcm: implement snd_ctl_abort() and snd_pcm_abort() functions
Upon an interrupt, it is necessary to abort the wait loops with the EINTR error code. Introduce snd_*_abort() functions to handle this case. Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
730c833dd8
commit
e23fb2c4de
7 changed files with 17 additions and 4 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue