I'm trying to fix brutefir to properly drain the driver before exiting.
This sequence does not work on a running stream. snd_pcm_nonblock() removes the O_NONBLOCK flag from the file handle but the change does not get copied to stream->f_flags. snd_pcm_drain() returns -EAGAIN since the flags have not be copied.
snd_pcm_nonblock(handles[IO][n], 0); snd_pcm_drain(handles[IO][n]); snd_pcm_nonblock(handles[IO][n], SND_PCM_NONBLOCK);
static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state) { printk("snd_pcm_pre_drain_init flags %x\n", substream->f_flags); if (substream->f_flags & O_NONBLOCK) return -EAGAIN; printk("snd_pcm_pre_drain_init 1\n"); substream->runtime->trigger_master = substream; return 0; }
Searching through the ALSA code the only way f_flags gets copied from the file handle to the stream handle is via snd_pcm_prepare(). But I can't do a snd_pcm_prepare() on a running stream. I can't find any way to change the NONBLOCK status on a running stream.
I also tried implementing the wait for drain the the user app. snd_pcm_drain() always returns -EAGAIN of O_NONBLOCK is set. It can't be used to poll for the drain status.
So how do I wait for a stream to drain?