Fix snd_pcm_wait() for multiple pollfd's

Fixed snd_pcm_wait() to handle multiple pollfd's.
This commit is contained in:
Takashi Iwai 2005-05-18 13:28:06 +00:00
parent a6d3b9e4e0
commit d5b9823447

View 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) int snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout)
{ {
struct pollfd pfd; struct pollfd *pfd;
unsigned short revents; unsigned short *revents;
int err, err_poll; 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) if (err < 0)
return err; return err;
if (err != 1) { if (err != npfds) {
SNDMSG("invalid poll descriptors %d\n", err); SNDMSG("invalid poll descriptors %d\n", err);
return -EIO; return -EIO;
} }
__retry: do {
err_poll = poll(&pfd, 1, timeout); err_poll = poll(pfd, npfds, timeout);
if (err_poll < 0) if (err_poll < 0)
return -errno; return -errno;
err = snd_pcm_poll_descriptors_revents(pcm, &pfd, 1, &revents); if (! err_poll)
if (err < 0) break;
return err; err = snd_pcm_poll_descriptors_revents(pcm, pfd, npfds, revents);
if (revents & (POLLERR | POLLNVAL)) { if (err < 0)
/* check more precisely */ return err;
switch (snd_pcm_state(pcm)) { pollio = 0;
case SND_PCM_STATE_XRUN: for (i = 0; i < npfds; i++) {
return -EPIPE; if (revents[i] & (POLLERR | POLLNVAL)) {
case SND_PCM_STATE_SUSPENDED: /* check more precisely */
return -ESTRPIPE; switch (snd_pcm_state(pcm)) {
case SND_PCM_STATE_DISCONNECTED: case SND_PCM_STATE_XRUN:
return -ENOTTY; /* linux VFS does this? */ return -EPIPE;
default: case SND_PCM_STATE_SUSPENDED:
return -EIO; return -ESTRPIPE;
case SND_PCM_STATE_DISCONNECTED:
return -ENOTTY; /* linux VFS does this? */
default:
return -EIO;
}
}
if ((revents[i] & (POLLIN | POLLOUT)) == 0)
continue;
pollio++;
} }
} } while (! pollio);
if ((revents & (POLLIN | POLLOUT)) == 0)
goto __retry;
#if 0 /* very useful code to test poll related problems */ #if 0 /* very useful code to test poll related problems */
{ {
snd_pcm_sframes_t avail_update; snd_pcm_sframes_t avail_update;