]> git.alsa-project.org Git - alsa-lib.git/commitdiff
control, pcm: implement snd_ctl_abort() and snd_pcm_abort() functions
authorJaroslav Kysela <perex@perex.cz>
Mon, 8 Apr 2013 11:28:03 +0000 (13:28 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 8 Apr 2013 11:28:03 +0000 (13:28 +0200)
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>
include/control.h
include/pcm.h
src/control/control.c
src/control/control_local.h
src/control/hcontrol.c
src/pcm/pcm.c
src/pcm/pcm_local.h

index e8408355b988d63cf753b6e6ee40c242dc65a7dd..27fe2ac8c0f7b98a2cbd848a0d7bb823f426b545 100644 (file)
@@ -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);
index 22356784e078390d8e10da1867b213e0fe5a6dab..549d6292a70b231e2f0bcc32e5c85a0a6a3746af 100644 (file)
@@ -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);
index 66277efe33df74043dd08dadfccfc06cad0a7193..5687ce1490730ec7eef439ea3ecc690372779828 100644 (file)
@@ -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)
index 49150d8dec0e93fa9b50440ff1cf9994c69af221..9594ae51a57fea6b2c2c28e3b88ff46ca892acbf 100644 (file)
@@ -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)
index ee1d907985f21b97f0650a0eea689b44dabf07a6..7645c5733853b2f39d06c88e5e239f2e306aee91 100644 (file)
@@ -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;
                }
index 0868dd5811b9c300ecf351fece4d752078127f2f..38febb9d13f3efe11b2cb10db5a4cb4b3ca99c21 100644 (file)
@@ -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;
                 }
index 63b9036f551fbc0fa90aaa04e428f2e738ade3e7..e1c0baa871f6afef812f738b795f96267c385d4d 100644 (file)
@@ -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)