summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2023-05-03 11:48:35 +0200
committerJaroslav Kysela <perex@perex.cz>2023-05-03 15:59:15 +0200
commit507d906abbf7f314d59a0b470ca6c29ca958b63c (patch)
tree69f222e78f9b501cb7956951589026ba0251836b
parentd6d5982d3ae68b72a1a53420b77ac269ef93d40e (diff)
downloadalsa-lib-507d906abbf7f314d59a0b470ca6c29ca958b63c.tar.gz
pcm: add SND_CTL_EINTR open mode
Add possibility to return -EINTR instead waiting for the event. The applications may want to handle -EINTR condition themselves. BugLink: https://github.com/alsa-project/alsa-lib/issues/228 Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r--include/control.h3
-rw-r--r--src/control/control.c3
-rw-r--r--src/control/control_ext.c2
-rw-r--r--src/control/control_hw.c2
-rw-r--r--src/control/control_local.h3
-rw-r--r--src/control/control_remap.c4
-rw-r--r--src/control/control_shm.c2
-rw-r--r--src/control/hcontrol.c2
8 files changed, 13 insertions, 8 deletions
diff --git a/include/control.h b/include/control.h
index e386ecec..d0c40d2f 100644
--- a/include/control.h
+++ b/include/control.h
@@ -356,6 +356,9 @@ typedef enum _snd_ctl_type {
/** Read only (flag for open mode) \hideinitializer */
#define SND_CTL_READONLY 0x0004
+/** Return EINTR instead blocking (flag for open mode) \hideinitializer */
+#define SND_CTL_EINTR 0x0080
+
/** CTL handle */
typedef struct _snd_ctl snd_ctl_t;
diff --git a/src/control/control.c b/src/control/control.c
index 91415b51..c4ca74ec 100644
--- a/src/control/control.c
+++ b/src/control/control.c
@@ -265,13 +265,14 @@ int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock)
}
#ifndef DOC_HIDDEN
-int snd_ctl_new(snd_ctl_t **ctlp, snd_ctl_type_t type, const char *name)
+int snd_ctl_new(snd_ctl_t **ctlp, snd_ctl_type_t type, const char *name, int mode)
{
snd_ctl_t *ctl;
ctl = calloc(1, sizeof(*ctl));
if (!ctl)
return -ENOMEM;
ctl->type = type;
+ ctl->mode = mode;
if (name)
ctl->name = strdup(name);
INIT_LIST_HEAD(&ctl->async_handlers);
diff --git a/src/control/control_ext.c b/src/control/control_ext.c
index 515f7882..0dcc8538 100644
--- a/src/control/control_ext.c
+++ b/src/control/control_ext.c
@@ -716,7 +716,7 @@ int snd_ctl_ext_create(snd_ctl_ext_t *ext, const char *name, int mode)
return -ENXIO;
}
- err = snd_ctl_new(&ctl, SND_CTL_TYPE_EXT, name);
+ err = snd_ctl_new(&ctl, SND_CTL_TYPE_EXT, name, mode);
if (err < 0)
return err;
diff --git a/src/control/control_hw.c b/src/control/control_hw.c
index 0ed9f6b2..02636910 100644
--- a/src/control/control_hw.c
+++ b/src/control/control_hw.c
@@ -444,7 +444,7 @@ int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card, int mode)
hw->fd = fd;
hw->protocol = ver;
- err = snd_ctl_new(&ctl, SND_CTL_TYPE_HW, name);
+ err = snd_ctl_new(&ctl, SND_CTL_TYPE_HW, name, mode);
if (err < 0) {
close(fd);
free(hw);
diff --git a/src/control/control_local.h b/src/control/control_local.h
index 973fa04c..b84dc429 100644
--- a/src/control/control_local.h
+++ b/src/control/control_local.h
@@ -62,6 +62,7 @@ struct _snd_ctl {
snd_ctl_type_t type;
const snd_ctl_ops_t *ops;
void *private_data;
+ int mode;
int nonblock;
int poll_fd;
struct list_head async_handlers;
@@ -93,7 +94,7 @@ struct _snd_hctl {
/* make local functions really local */
#define snd_ctl_new snd1_ctl_new
-int snd_ctl_new(snd_ctl_t **ctlp, snd_ctl_type_t type, const char *name);
+int snd_ctl_new(snd_ctl_t **ctlp, snd_ctl_type_t type, const char *name, int mode);
int _snd_ctl_poll_descriptor(snd_ctl_t *ctl);
#define _snd_ctl_async_descriptor _snd_ctl_poll_descriptor
int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card, int mode);
diff --git a/src/control/control_remap.c b/src/control/control_remap.c
index 4914f960..5bc56608 100644
--- a/src/control/control_remap.c
+++ b/src/control/control_remap.c
@@ -1148,7 +1148,7 @@ static int parse_map(snd_ctl_remap_t *priv, snd_config_t *conf)
* changed in future.
*/
int snd_ctl_remap_open(snd_ctl_t **handlep, const char *name, snd_config_t *remap,
- snd_config_t *map, snd_ctl_t *child, int mode ATTRIBUTE_UNUSED)
+ snd_config_t *map, snd_ctl_t *child, int mode)
{
snd_ctl_remap_t *priv;
snd_ctl_t *ctl;
@@ -1195,7 +1195,7 @@ int snd_ctl_remap_open(snd_ctl_t **handlep, const char *name, snd_config_t *rema
priv->numid_remap_active = priv->map_items > 0;
priv->child = child;
- err = snd_ctl_new(&ctl, SND_CTL_TYPE_REMAP, name);
+ err = snd_ctl_new(&ctl, SND_CTL_TYPE_REMAP, name, mode);
if (err < 0) {
result = err;
goto _err;
diff --git a/src/control/control_shm.c b/src/control/control_shm.c
index d7297e6c..3d1555ee 100644
--- a/src/control/control_shm.c
+++ b/src/control/control_shm.c
@@ -502,7 +502,7 @@ int snd_ctl_shm_open(snd_ctl_t **handlep, const char *name, const char *sockname
shm->socket = sock;
shm->ctrl = ctrl;
- err = snd_ctl_new(&ctl, SND_CTL_TYPE_SHM, name);
+ err = snd_ctl_new(&ctl, SND_CTL_TYPE_SHM, name, mode);
if (err < 0) {
result = err;
goto _err;
diff --git a/src/control/hcontrol.c b/src/control/hcontrol.c
index 0cac8956..18ddc16b 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 && !CTLINABORT(hctl->ctl))
+ if (errno == EINTR && !CTLINABORT(hctl->ctl) && !(hctl->ctl->mode & SND_CTL_EINTR))
continue;
return -errno;
}