On Thu, 22 Mar 2018 14:48:55 +0100, <twischer@xxxxxxxxxxxxxx> wrote: > > > Hi Takashi, > > > Why not poll()? > > > IOW, why ioplug must be handled specially regarding the non-blocking > >operation? The normal kernel driver behaves like that (returning > > -EAGAIN, and let apps to sync with poll()). > > > What do you think about the following solution? > > (I thought the whole time that you have to use snd_pcm_wait() to wait for drain > in nonblocking mode but you have to use the poll_descriptors directly.) > > Know I am expecting that the user is calling poll() > if snd_pcm_drain() returns -EAGAIN and > the user has to call snd_pcm_drain() again after poll returns > to check if drain is done. Well, the drain callback *should* block and wait until drained. That was the intention of the callback. What I suggested instead is that ioctl shouldn't call drain callback in non-blocking mode, but it should return -EAGAIN there. That said, a change like below. And in the plugin side, it can assume the blocking mode and simply waits until drained. thanks, Takashi --- diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c index 8c0ed4836365..33f7c5c27b6f 100644 --- a/src/pcm/pcm_ioplug.c +++ b/src/pcm/pcm_ioplug.c @@ -494,12 +494,37 @@ static int snd_pcm_ioplug_drain(snd_pcm_t *pcm) ioplug_priv_t *io = pcm->private_data; int err; - if (io->data->state == SND_PCM_STATE_OPEN) + switch (io->data->state) { + case SND_PCM_STATE_OPEN: + case SND_PCM_STATE_DISCONNECTED: + case SND_PCM_STATE_SUSPENDED: return -EBADFD; + case SND_PCM_STATE_PREPARED: + if (pcm->stream == SND_PCM_STREAM_PLAYBACK) { + snd_pcm_lock(pcm); + err = snd_pcm_ioplug_start(pcm); + snd_pcm_unlock(pcm); + if (err < 0) + return err; + io->data->state = SND_PCM_STATE_DRAINING; + } + break; + case SND_PCM_STATE_RUNNING: + io->data->state = SND_PCM_STATE_DRAINING; + break; + } + + if (io->data->state == SND_PCM_STATE_DRAINING) { + if (io->data->nonblock) + return -EAGAIN; + + if (io->data->callback->drain) { + err = io->data->callback->drain(io->data); + if (err < 0) + return err; + } + } - io->data->state = SND_PCM_STATE_DRAINING; - if (io->data->callback->drain) - io->data->callback->drain(io->data); snd_pcm_lock(pcm); err = snd_pcm_ioplug_drop(pcm); snd_pcm_unlock(pcm); _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel