diff --git a/src/asound/bluealsa-pcm.c b/src/asound/bluealsa-pcm.c index 29af8deba..8426ffa5e 100644 --- a/src/asound/bluealsa-pcm.c +++ b/src/asound/bluealsa-pcm.c @@ -692,6 +692,10 @@ static int bluealsa_drain(snd_pcm_ioplug_t *io) { return -EIO; } + /* For a non-blocking drain, we do not wait for the drain to complete. */ + if (io->nonblock == 1) + return -EAGAIN; + bool aborted = false; struct pollfd pfd = { pcm->event_fd, POLLIN, 0 }; @@ -1002,7 +1006,8 @@ static int bluealsa_poll_revents(snd_pcm_ioplug_t *io, struct pollfd *pfd, goto fail; /* This call synchronizes the ring buffer pointers and updates the - * ioplug state. */ + * ioplug state. For non-blocking drains it also causes ioplug to drop + * the stream when the buffer is empty. */ snd_pcm_sframes_t avail = snd_pcm_avail(io->pcm); /* ALSA expects that the event will match stream direction, e.g. @@ -1015,8 +1020,13 @@ static int bluealsa_poll_revents(snd_pcm_ioplug_t *io, struct pollfd *pfd, switch (io->state) { case SND_PCM_STATE_SETUP: + /* To support non-blocking drain we must report a POLLOUT event + * for playback PCMs here, because the above call to + * snd_pcm_avail() may have changed the state to + * SND_PCM_STATE_SETUP. */ + if (io->stream == SND_PCM_STREAM_CAPTURE) + *revents = 0; ready = false; - *revents = 0; break; case SND_PCM_STATE_PREPARED: /* capture poll should block forever */