From d5b98234478680c4afdf475988b8952605f66ff8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 18 May 2005 13:28:06 +0000 Subject: [PATCH] Fix snd_pcm_wait() for multiple pollfd's Fixed snd_pcm_wait() to handle multiple pollfd's. --- src/pcm/pcm.c | 66 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index c12a17d0..69e7a530 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -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; -- 2.47.3