]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Added snd_*_poll_descriptors_revents functions.
authorJaroslav Kysela <perex@perex.cz>
Fri, 30 Nov 2001 17:36:45 +0000 (17:36 +0000)
committerJaroslav Kysela <perex@perex.cz>
Fri, 30 Nov 2001 17:36:45 +0000 (17:36 +0000)
15 files changed:
include/control.h
include/hwdep.h
include/mixer.h
include/pcm.h
include/rawmidi.h
include/seq.h
include/timer.h
src/control/control.c
src/hwdep/hwdep.c
src/mixer/mixer.c
src/pcm/pcm.c
src/rawmidi/rawmidi.c
src/seq/seq.c
src/timer/timer.c
test/pcm.c

index 0567e1a2ffde2155c161a3a0b162211bbdd92fd1..2e5dca31eab3a8d490fb3da2afecd4ec491553d2 100644 (file)
@@ -201,6 +201,7 @@ int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl,
 snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler);
 int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl);
 int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space);
+int snd_ctl_poll_descriptors_revents(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
 int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe);
 int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info);
 int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t * list);
index 54be9bc4bfa4c0535d3a2229e302ce9f776e9be6..0e33e78bbeef44eacd91aa95f203180173953e93 100644 (file)
@@ -81,6 +81,7 @@ typedef struct _snd_hwdep snd_hwdep_t;
 int snd_hwdep_open(snd_hwdep_t **hwdep, const char *name, int mode);
 int snd_hwdep_close(snd_hwdep_t *hwdep);
 int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int space);
+int snd_hwdep_poll_descriptors_revents(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
 int snd_hwdep_nonblock(snd_hwdep_t *hwdep, int nonblock);
 int snd_hwdep_info(snd_hwdep_t *hwdep, snd_hwdep_info_t * info);
 int snd_hwdep_ioctl(snd_hwdep_t *hwdep, unsigned int request, void * arg);
index 3b1aa740cf9636ea9dafbf72d2361be301c160e0..cd4714deacfa09b47f5126d4bb493099aa28d4c8 100644 (file)
@@ -90,6 +90,7 @@ int snd_mixer_attach(snd_mixer_t *mixer, const char *name);
 int snd_mixer_detach(snd_mixer_t *mixer, const char *name);
 int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer);
 int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int space);
+int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
 int snd_mixer_load(snd_mixer_t *mixer);
 void snd_mixer_free(snd_mixer_t *mixer);
 int snd_mixer_wait(snd_mixer_t *mixer, int timeout);
index 2782b34337bfe8c6ec39955e53fd724944d1d4ec..a1cfc829d3288ac9ccb53a83be513a99268a953e 100644 (file)
@@ -362,6 +362,7 @@ snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm);
 snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm);
 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);
 int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm, 
                              snd_async_callback_t callback, void *private_data);
@@ -710,7 +711,7 @@ void snd_pcm_subformat_mask_copy(snd_pcm_subformat_mask_t *dst, const snd_pcm_su
 void snd_pcm_subformat_mask_none(snd_pcm_subformat_mask_t *mask);
 void snd_pcm_subformat_mask_any(snd_pcm_subformat_mask_t *mask);
 int snd_pcm_subformat_mask_test(const snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val);
-int snd_pcm_subformat_mask_empty(const snd_pcm_format_mask_t *mask);
+int snd_pcm_subformat_mask_empty(const snd_pcm_subformat_mask_t *mask);
 void snd_pcm_subformat_mask_set(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val);
 void snd_pcm_subformat_mask_reset(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val);
 
index ba35584151bfbad59a7a86362d5b0dfd8178ba2a..579da4b56a8de853cfe546b89e993979080fded2 100644 (file)
@@ -84,6 +84,7 @@ int snd_rawmidi_open_lconf(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi,
 int snd_rawmidi_close(snd_rawmidi_t *rmidi);
 int snd_rawmidi_poll_descriptors_count(snd_rawmidi_t *rmidi);
 int snd_rawmidi_poll_descriptors(snd_rawmidi_t *rmidi, struct pollfd *pfds, unsigned int space);
+int snd_rawmidi_poll_descriptors_revents(snd_rawmidi_t *rawmidi, struct pollfd *pfds, unsigned int nfds, unsigned short *revent);
 int snd_rawmidi_nonblock(snd_rawmidi_t *rmidi, int nonblock);
 size_t snd_rawmidi_info_sizeof(void);
 /** \hideinitializer
index 3cdd1ceefd4a5f413ede80e34294f8c30a42cfa6..c0980c5a14835905dee06e8335dc03fac7eb9b9e 100644 (file)
@@ -90,6 +90,7 @@ snd_seq_type_t snd_seq_type(snd_seq_t *seq);
 int snd_seq_close(snd_seq_t *handle);
 int snd_seq_poll_descriptors_count(snd_seq_t *handle, short events);
 int snd_seq_poll_descriptors(snd_seq_t *handle, struct pollfd *pfds, unsigned int space, short events);
+int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
 int snd_seq_nonblock(snd_seq_t *handle, int nonblock);
 int snd_seq_client_id(snd_seq_t *handle);
 
index b6bd11e5c45f31dfa75a0428b721da99ce088c08..5af762b26b362fe0b7d14000c11551b9d74adeb9 100644 (file)
@@ -110,6 +110,7 @@ int snd_timer_open_lconf(snd_timer_t **handle, const char *name, int mode, snd_c
 int snd_timer_close(snd_timer_t *handle);
 int snd_timer_poll_descriptors_count(snd_timer_t *handle);
 int snd_timer_poll_descriptors(snd_timer_t *handle, struct pollfd *pfds, unsigned int space);
+int snd_timer_poll_descriptors_revents(snd_timer_t *timer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
 int snd_timer_info(snd_timer_t *handle, snd_timer_info_t *timer);
 int snd_timer_params(snd_timer_t *handle, snd_timer_params_t *params);
 int snd_timer_status(snd_timer_t *handle, snd_timer_status_t *status);
index c8292a09243c5d4364baee05c802e7d03ed02842..db0d8375b38e9c0225153628b73b025c6e9ad3a5 100644 (file)
@@ -160,15 +160,33 @@ int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl)
  */
 int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space)
 {
-       assert(ctl);
+       assert(ctl && pfds);
        if (space > 0) {
                pfds->fd = ctl->poll_fd;
-               pfds->events = POLLIN;
+               pfds->events = POLLIN|POLLERR;
                return 1;
        }
        return 0;
 }
 
+/**
+ * \brief get returned events from poll descriptors
+ * \param ctl CTL handle
+ * \param pfds array of poll descriptors
+ * \param nfds count of poll descriptors
+ * \param revents returned events
+ * \return zero if success, otherwise a negative error code
+ */
+int snd_ctl_poll_descriptors_revents(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
+{
+       assert(ctl && pfds && revents);
+       if (nfds == 1) {
+               *revents = pfds->revents;
+                return 0;
+       }
+       return -EINVAL;
+}
+
 /**
  * \brief Ask to be informed about events (poll, #snd_ctl_async, #snd_ctl_read)
  * \param ctl CTL handle
index bf014d87c2ff28d2e010b17fd6aeed3f5980f6aa..cba186b5ef68262fb0a0adfafe318a68e434bf2f 100644 (file)
@@ -260,13 +260,13 @@ int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned
                pfds->fd = hwdep->poll_fd;
                switch (hwdep->mode & O_ACCMODE) {
                case O_WRONLY:
-                       pfds->events = POLLOUT;
+                       pfds->events = POLLOUT|POLLERR;
                        break;
                case O_RDONLY:
-                       pfds->events = POLLIN;
+                       pfds->events = POLLIN|POLLERR;
                        break;
                case O_RDWR:
-                       pfds->events = POLLOUT|POLLIN;
+                       pfds->events = POLLOUT|POLLIN|POLLERR;
                        break;
                default:
                        return -EIO;
@@ -276,6 +276,24 @@ int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned
        return 0;
 }
 
+/**
+ * \brief get returned events from poll descriptors
+ * \param hwdep HwDep  handle
+ * \param pfds array of poll descriptors
+ * \param nfds count of poll descriptors
+ * \param revents returned events
+ * \return zero if success, otherwise a negative error code
+ */
+int snd_hwdep_poll_descriptors_revents(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
+{
+        assert(hwdep && pfds && revents);
+        if (nfds == 1) {
+                *revents = pfds->revents;
+                return 0;
+        }
+        return -EINVAL;
+}                                                                       
+                                                                       
 /**
  * \brief set nonblock mode
  * \param hwdep HwDep handle
index 0053aed849a427fc264c1131c27e3614633311df..71f5539e8c0f6b8882b7df146c1d6842bda9b18b 100644 (file)
@@ -599,6 +599,28 @@ int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned
        return count;
 }
 
+/**
+ * \brief get returned events from poll descriptors
+ * \param mixer Mixer handle
+ * \param pfds array of poll descriptors
+ * \param nfds count of poll descriptors
+ * \param revents returned events
+ * \return zero if success, otherwise a negative error code
+ */
+int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
+{
+       unsigned int idx;
+       unsigned short res;
+        assert(mixer && pfds && revents);
+       if (nfds == 0)
+               return -EINVAL;
+       res = 0;
+       for (idx = 0; idx < nfds; idx++)
+               res |= pfds->revents & (POLLIN|POLLERR);
+       *revents = res;
+       return 0;
+}
+
 /**
  * \brief Wait for a mixer to become ready (i.e. at least one event pending)
  * \param mixer Mixer handle
index ba9b56dee71ef0b52000297494aff615d42e3b2c..b221f9258c5e1e1374a95ab2150372dd205072d7 100644 (file)
@@ -1003,14 +1003,33 @@ 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)
 {
-       assert(pcm);
-       if (space >= 1) {
+       assert(pcm && pfds);
+       if (space >= 1 && pfds) {
                pfds->fd = pcm->poll_fd;
-               pfds->events = pcm->stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN;
-       }
+               pfds->events = pcm->stream == SND_PCM_STREAM_PLAYBACK ? (POLLOUT|POLLERR) : (POLLIN|POLLERR);
+       } else
+               return 0;
        return 1;
 }
 
+/**
+ * \brief get returned events from poll descriptors
+ * \param pcm PCM handle
+ * \param pfds array of poll descriptors
+ * \param nfds count of poll descriptors
+ * \param revents returned events
+ * \return zero if success, otherwise a negative error code
+ */
+int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
+{
+       assert(pcm && pfds && revents);
+       if (nfds == 1) {
+               *revents = pfds->revents;
+               return 0;
+       }
+       return -EINVAL;
+}
+
 #ifndef DOC_HIDDEN
 #define STATE(v) [SND_PCM_STATE_##v] = #v
 #define STREAM(v) [SND_PCM_STREAM_##v] = #v
index bef3d50d31a066882fe9ce7cc0dda4466559e762..c6652a237a7ab0e9fb1e881f08168132aa686dc7 100644 (file)
@@ -313,12 +313,30 @@ int snd_rawmidi_poll_descriptors(snd_rawmidi_t *rawmidi, struct pollfd *pfds, un
        assert(rawmidi);
        if (space >= 1) {
                pfds->fd = rawmidi->poll_fd;
-               pfds->events = rawmidi->stream == SND_RAWMIDI_STREAM_OUTPUT ? POLLOUT : POLLIN;
+               pfds->events = rawmidi->stream == SND_RAWMIDI_STREAM_OUTPUT ? (POLLOUT|POLLERR) : (POLLIN|POLLERR);
                return 1;
        }
        return 0;
 }
 
+/**
+ * \brief get returned events from poll descriptors
+ * \param pcm rawmidi RawMidi handle
+ * \param pfds array of poll descriptors
+ * \param nfds count of poll descriptors
+ * \param revents returned events
+ * \return zero if success, otherwise a negative error code
+ */
+int snd_rawmidi_poll_descriptors_revents(snd_rawmidi_t *rawmidi, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
+{
+        assert(rawmidi && pfds && revents);
+        if (nfds == 1) {
+                *revents = pfds->revents;
+                return 0;
+        }
+        return -EINVAL;
+}
+
 /**
  * \brief set nonblock mode
  * \param rawmidi RawMidi handle
index 98b3cceda407d43b9d1ba539e66036747772005f..66e52b3a95be74fbbacf983ce314352fdecccfe7 100644 (file)
@@ -305,11 +305,11 @@ int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int s
        assert(seq);
        if ((events & POLLIN) && space >= 1) {
                assert(seq->streams & SND_SEQ_OPEN_INPUT);
-               revents |= POLLIN;
+               revents |= POLLIN|POLLERR;
        }
        if ((events & POLLOUT) && space >= 1) {
                assert(seq->streams & SND_SEQ_OPEN_INPUT);
-               revents |= POLLOUT;
+               revents |= POLLOUT|POLLERR;
        }
        if (!revents)
                return 0;
@@ -318,6 +318,24 @@ int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int s
        return 1;
 }
 
+/**
+ * \brief get returned events from poll descriptors
+ * \param seq sequencer handle
+ * \param pfds array of poll descriptors
+ * \param nfds count of poll descriptors
+ * \param revents returned events
+ * \return zero if success, otherwise a negative error code
+ */
+int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
+{
+        assert(seq && pfds && revents);
+        if (nfds == 1) {
+                *revents = pfds->revents;
+                return 0;
+        }
+        return -EINVAL;
+}
+
 /**
  * \brief Set nonblock mode
  * \param seq sequencer handle
index 5ccc1cb13e9b5fc92230e486f85d203b9cba089d..352c10e3fb003800bea28543b38ece28e36fd678 100644 (file)
@@ -261,13 +261,13 @@ int snd_timer_poll_descriptors(snd_timer_t *timer, struct pollfd *pfds, unsigned
                pfds->fd = timer->poll_fd;
                switch (timer->mode & O_ACCMODE) {
                case O_WRONLY:
-                       pfds->events = POLLOUT;
+                       pfds->events = POLLOUT|POLLERR;
                        break;
                case O_RDONLY:
-                       pfds->events = POLLIN;
+                       pfds->events = POLLIN|POLLERR;
                        break;
                case O_RDWR:
-                       pfds->events = POLLOUT|POLLIN;
+                       pfds->events = POLLOUT|POLLIN|POLLERR;
                        break;
                default:
                        return -EIO;
@@ -277,6 +277,24 @@ int snd_timer_poll_descriptors(snd_timer_t *timer, struct pollfd *pfds, unsigned
        return 0;
 }
 
+/**
+ * \brief get returned events from poll descriptors
+ * \param timer timer handle
+ * \param pfds array of poll descriptors
+ * \param nfds count of poll descriptors
+ * \param revents returned events
+ * \return zero if success, otherwise a negative error code
+ */
+int snd_timer_poll_descriptors_revents(snd_timer_t *timer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
+{
+        assert(timer && pfds && revents);
+        if (nfds == 1) {
+                *revents = pfds->revents;
+                return 0;
+        }
+        return -EINVAL;
+}
+
 /**
  * \brief set nonblock mode
  * \param timer timer handle
index 2851feca7b7592a6bb4894d155083f37cb232ee2..7344b0bffdb9d2676d1ea4a19dd7d14d04f1e880 100644 (file)
@@ -226,22 +226,17 @@ static int write_loop(snd_pcm_t *handle,
  *   Transfer method - write and wait for room in buffer using poll
  */
 
-static int wait_for_poll(struct pollfd *ufds, int count)
+static int wait_for_poll(snd_pcm_t *handle, struct pollfd *ufds, unsigned int count)
 {
-       int i;
-       unsigned int events;
+       unsigned short revents;
 
        while (1) {
                poll(ufds, count, -1);
-               for (i = 0; i < count; i++) {
-                       events = ufds[i].revents;
-                       if (events & POLLERR) {
-                               printf("Poll - POLLERR detected\n");
-                               return -EIO;
-                       }
-                       if (events & POLLOUT)
-                               return 0;
-               }
+               snd_pcm_poll_descriptors_revents(handle, ufds, count, &revents);
+               if (revents & POLLERR)
+                       return -EIO;
+               if (revents & POLLOUT)
+                       return 0;
        }
 }
 
@@ -252,7 +247,7 @@ static int write_and_poll_loop(snd_pcm_t *handle,
        struct pollfd *ufds;
        double phase = 0;
        signed short *ptr;
-       int err, count, cptr;
+       int err, count, cptr, init;
 
        count = snd_pcm_poll_descriptors_count (handle);
        if (count <= 0) {
@@ -270,11 +265,24 @@ static int write_and_poll_loop(snd_pcm_t *handle,
                return err;
        }
 
+       init = 1;
        while (1) {
-               err = wait_for_poll(ufds, count);
-               if (err < 0) {
-                       printf("Wait for poll failed\n");
-                       return err;
+               if (!init) {
+                       err = wait_for_poll(handle, ufds, count);
+                       if (err < 0) {
+                               if (snd_pcm_state(handle) == SND_PCM_STATE_XRUN ||
+                                   snd_pcm_state(handle) == SND_PCM_STATE_SUSPENDED) {
+                                       err = snd_pcm_state(handle) == SND_PCM_STATE_XRUN ? -EPIPE : -ESTRPIPE;
+                                       if (xrun_recovery(handle, err) < 0) {
+                                               printf("Write error: %s\n", snd_strerror(err));
+                                               exit(EXIT_FAILURE);
+                                       }
+                                       init = 1;
+                               } else {
+                                       printf("Wait for poll failed\n");
+                                       return err;
+                               }
+                       }
                }
 
                generate_sine(areas, 0, period_size, &phase);
@@ -287,18 +295,31 @@ static int write_and_poll_loop(snd_pcm_t *handle,
                                        printf("Write error: %s\n", snd_strerror(err));
                                        exit(EXIT_FAILURE);
                                }
+                               init = 1;
                                break;  /* skip one period */
                        }
+                       if (snd_pcm_state(handle) == SND_PCM_STATE_RUNNING)
+                               init = 0;
                        ptr += err * channels;
                        cptr -= err;
                        if (cptr == 0)
                                break;
                        /* it is possible, that initial buffer cannot store */
                        /* all data from last period, so wait awhile */
-                       err = wait_for_poll(ufds, count);
+                       err = wait_for_poll(handle, ufds, count);
                        if (err < 0) {
-                               printf("Wait for poll failed\n");
-                               return err;
+                               if (snd_pcm_state(handle) == SND_PCM_STATE_XRUN ||
+                                   snd_pcm_state(handle) == SND_PCM_STATE_SUSPENDED) {
+                                       err = snd_pcm_state(handle) == SND_PCM_STATE_XRUN ? -EPIPE : -ESTRPIPE;
+                                       if (xrun_recovery(handle, err) < 0) {
+                                               printf("Write error: %s\n", snd_strerror(err));
+                                               exit(EXIT_FAILURE);
+                                       }
+                                       init = 1;
+                               } else {
+                                       printf("Wait for poll failed\n");
+                                       return err;
+                               }
                        }
                }
        }