Fix poll after XRUN with dmix

Fix the behavior of poll after XRUN with dmix plugin.
Poll should return immediately with an XRUN stream.
This commit is contained in:
Takashi Iwai 2005-05-23 08:48:46 +00:00
parent b0ee34e757
commit 4c6809bf30
2 changed files with 8 additions and 6 deletions

View file

@ -456,12 +456,12 @@ int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned in
{ {
snd_pcm_direct_t *dmix = pcm->private_data; snd_pcm_direct_t *dmix = pcm->private_data;
unsigned short events; unsigned short events;
int empty = 0;
assert(pfds && nfds == 1 && revents); assert(pfds && nfds == 1 && revents);
events = pfds[0].revents; events = pfds[0].revents;
if (events & POLLIN) { if (events & POLLIN) {
snd_pcm_uframes_t avail; snd_pcm_uframes_t avail;
int empty;
snd_pcm_avail_update(pcm); snd_pcm_avail_update(pcm);
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) { if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
events |= POLLOUT; events |= POLLOUT;
@ -471,10 +471,6 @@ int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned in
avail = snd_pcm_mmap_capture_avail(pcm); avail = snd_pcm_mmap_capture_avail(pcm);
} }
empty = avail < pcm->avail_min; empty = avail < pcm->avail_min;
if (empty) {
snd_pcm_direct_clear_timer_queue(dmix);
events &= ~(POLLOUT|POLLIN);
}
} }
switch (snd_pcm_state(dmix->spcm)) { switch (snd_pcm_state(dmix->spcm)) {
case SND_PCM_STATE_XRUN: case SND_PCM_STATE_XRUN:
@ -482,6 +478,10 @@ int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned in
events |= POLLERR; events |= POLLERR;
break; break;
default: default:
if (empty) {
snd_pcm_direct_clear_timer_queue(dmix);
events &= ~(POLLOUT|POLLIN);
}
break; break;
} }
*revents = events; *revents = events;

View file

@ -312,7 +312,7 @@ static int _snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm, int do_slave_sync)
dmix->avail_max = avail; dmix->avail_max = avail;
if (avail >= pcm->stop_threshold) { if (avail >= pcm->stop_threshold) {
struct timeval tv; struct timeval tv;
snd_pcm_direct_timer_stop(dmix); snd_timer_stop(dmix->timer);
gettimeofday(&tv, 0); gettimeofday(&tv, 0);
dmix->trigger_tstamp.tv_sec = tv.tv_sec; dmix->trigger_tstamp.tv_sec = tv.tv_sec;
dmix->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; dmix->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L;
@ -321,6 +321,8 @@ static int _snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm, int do_slave_sync)
return -EPIPE; return -EPIPE;
} }
dmix->state = SND_PCM_STATE_SETUP; dmix->state = SND_PCM_STATE_SETUP;
/* clear queue to remove pending poll events */
snd_pcm_direct_clear_timer_queue(dmix);
} }
return 0; return 0;
} }