]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Fix snd_pcm_wait() for multiple pollfd's
authorTakashi Iwai <tiwai@suse.de>
Wed, 18 May 2005 13:28:06 +0000 (13:28 +0000)
committerTakashi Iwai <tiwai@suse.de>
Wed, 18 May 2005 13:28:06 +0000 (13:28 +0000)
Fixed snd_pcm_wait() to handle multiple pollfd's.

src/pcm/pcm.c

index c12a17d02c0c48cc34856f4ca6109a5acec35d64..69e7a53018181357239b85d0059e0594772d0f28 100644 (file)
@@ -2218,39 +2218,53 @@ int snd_pcm_wait(snd_pcm_t *pcm, int timeout)
  */
 int snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout)
 {
-       struct pollfd pfd;
-       unsigned short revents;
-       int err, err_poll;
+       struct pollfd *pfd;
+       unsigned short *revents;
+       int i, npfds, pollio, err, err_poll;
        
-       err = snd_pcm_poll_descriptors(pcm, &pfd, 1);
+       npfds = snd_pcm_poll_descriptors_count(pcm);
+       if (npfds <= 0 || npfds >= 16) {
+               SNDERR("Invalid poll_fds %d\n", npfds);
+               return -EIO;
+       }
+       pfd = alloca(sizeof(*pfd) * npfds);
+       revents = alloca(sizeof(*revents) * npfds);
+       err = snd_pcm_poll_descriptors(pcm, pfd, npfds);
        if (err < 0)
                return err;
-       if (err != 1) {
+       if (err != npfds) {
                SNDMSG("invalid poll descriptors %d\n", err);
                return -EIO;
        }
-      __retry:
-       err_poll = poll(&pfd, 1, timeout);
-       if (err_poll < 0)
-               return -errno;
-       err = snd_pcm_poll_descriptors_revents(pcm, &pfd, 1, &revents);
-       if (err < 0)
-               return err;
-       if (revents & (POLLERR | POLLNVAL)) {
-               /* check more precisely */
-               switch (snd_pcm_state(pcm)) {
-               case SND_PCM_STATE_XRUN:
-                       return -EPIPE;
-               case SND_PCM_STATE_SUSPENDED:
-                       return -ESTRPIPE;
-               case SND_PCM_STATE_DISCONNECTED:
-                       return -ENOTTY; /* linux VFS does this? */
-               default:
-                       return -EIO;
+       do {
+               err_poll = poll(pfd, npfds, timeout);
+               if (err_poll < 0)
+                       return -errno;
+               if (! err_poll)
+                       break;
+               err = snd_pcm_poll_descriptors_revents(pcm, pfd, npfds, revents);
+               if (err < 0)
+                       return err;
+               pollio = 0;
+               for (i = 0; i < npfds; i++) {
+                       if (revents[i] & (POLLERR | POLLNVAL)) {
+                               /* check more precisely */
+                               switch (snd_pcm_state(pcm)) {
+                               case SND_PCM_STATE_XRUN:
+                                       return -EPIPE;
+                               case SND_PCM_STATE_SUSPENDED:
+                                       return -ESTRPIPE;
+                               case SND_PCM_STATE_DISCONNECTED:
+                                       return -ENOTTY; /* linux VFS does this? */
+                               default:
+                                       return -EIO;
+                               }
+                       }
+                       if ((revents[i] & (POLLIN | POLLOUT)) == 0)
+                               continue;
+                       pollio++;
                }
-       }
-       if ((revents & (POLLIN | POLLOUT)) == 0)
-               goto __retry;
+       } while (! pollio);
 #if 0 /* very useful code to test poll related problems */
        {
                snd_pcm_sframes_t avail_update;