]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Make snd_hctl_wait() respect the API
authorPierre Ossman <ossman@cendio.se>
Fri, 26 May 2006 15:27:00 +0000 (17:27 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 26 May 2006 15:27:00 +0000 (17:27 +0200)
snd_hctl_wait() currently makes a lot of assumptions that fall outside
the defined API. snd_pcm_wait(), however, follows the API nicely so the
new version is based on that.

Signed-off-by: Pierre Ossman <ossman@cendio.se>
src/control/hcontrol.c

index 5d20e7400b44100e06ad333867724a44eaf7d0a9..05d28832ee61ccb276826c73113a5d44830bf9d4 100644 (file)
@@ -657,22 +657,52 @@ unsigned int snd_hctl_get_count(snd_hctl_t *hctl)
  * \brief Wait for a HCTL to become ready (i.e. at least one event pending)
  * \param hctl HCTL handle
  * \param timeout maximum time in milliseconds to wait
- * \return 0 otherwise a negative error code on failure
+ * \return a positive value on success otherwise a negative error code
+ * \retval 0 timeout occurred
+ * \retval 1 an event is pending
  */
 int snd_hctl_wait(snd_hctl_t *hctl, int timeout)
 {
-       struct pollfd pfd;
-       int err;
-       err = snd_hctl_poll_descriptors(hctl, &pfd, 1);
+       struct pollfd *pfd;
+       unsigned short *revents;
+       int i, npfds, pollio, err, err_poll;
+       
+       npfds = snd_hctl_poll_descriptors_count(hctl);
+       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_hctl_poll_descriptors(hctl, pfd, npfds);
        if (err < 0)
                return err;
-       if (! err)
-               return 0;
-       assert(err == 1);
-       err = poll(&pfd, 1, timeout);
-       if (err < 0)
-               return -errno;
-       return 0;
+       if (err != npfds) {
+               SNDMSG("invalid poll descriptors %d\n", err);
+               return -EIO;
+       }
+       do {
+               pollio = 0;
+               err_poll = poll(pfd, npfds, timeout);
+               if (err_poll < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       return -errno;
+               }
+               if (! err_poll)
+                       break;
+               err = snd_hctl_poll_descriptors_revents(hctl, pfd, npfds, revents);
+               if (err < 0)
+                       return err;
+               for (i = 0; i < npfds; i++) {
+                       if (revents[i] & (POLLERR | POLLNVAL))
+                               return -EIO;
+                       if ((revents[i] & (POLLIN | POLLOUT)) == 0)
+                               continue;
+                       pollio++;
+               }
+       } while (! pollio);
+       return err_poll > 0 ? 1 : 0;
 }
 
 /**