]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Fix poll after XRUN with dmix
authorTakashi Iwai <tiwai@suse.de>
Mon, 23 May 2005 08:48:46 +0000 (08:48 +0000)
committerTakashi Iwai <tiwai@suse.de>
Mon, 23 May 2005 08:48:46 +0000 (08:48 +0000)
Fix the behavior of poll after XRUN with dmix plugin.
Poll should return immediately with an XRUN stream.

src/pcm/pcm_direct.c
src/pcm/pcm_dmix.c

index a8ce4a2276a1e0c322330e0e12f4781ce4a07f5f..14e4b8a5db6e2419516d37edbc46871e5ab0020b 100644 (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;
        unsigned short events;
+       int empty = 0;
 
        assert(pfds && nfds == 1 && revents);
        events = pfds[0].revents;
        if (events & POLLIN) {
                snd_pcm_uframes_t avail;
-               int empty;
                snd_pcm_avail_update(pcm);
                if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
                        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);
                }
                empty = avail < pcm->avail_min;
-               if (empty) {
-                       snd_pcm_direct_clear_timer_queue(dmix);
-                       events &= ~(POLLOUT|POLLIN);
-               }
        }
        switch (snd_pcm_state(dmix->spcm)) {
        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;
                break;
        default:
+               if (empty) {
+                       snd_pcm_direct_clear_timer_queue(dmix);
+                       events &= ~(POLLOUT|POLLIN);
+               }
                break;
        }
        *revents = events;
index e5104db4419ddd01ff49917c8c9cb413c4aa9b3c..2438468602d535f49314a0e42d4bac62d2cb8647 100644 (file)
@@ -312,7 +312,7 @@ static int _snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm, int do_slave_sync)
                dmix->avail_max = avail;
        if (avail >= pcm->stop_threshold) {
                struct timeval tv;
-               snd_pcm_direct_timer_stop(dmix);
+               snd_timer_stop(dmix->timer);
                gettimeofday(&tv, 0);
                dmix->trigger_tstamp.tv_sec = tv.tv_sec;
                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;
                }
                dmix->state = SND_PCM_STATE_SETUP;
+               /* clear queue to remove pending poll events */
+               snd_pcm_direct_clear_timer_queue(dmix);
        }
        return 0;
 }