[alsa-devel] dmix, snd_pcm_drain(), SND_PCM_NONBLOCK - bug?
Hi,
I have received a bug report for the Music Player Daemon which complains about a freezing MPD process, after I switched MPD's ALSA output to non-blocking mode:
https://bugs.musicpd.org/view.php?id=4662
This happens when snd_pcm_drain() is used on a dmix PCM which is in SND_PCM_NONBLOCK mode. snd_pcm_drain() will be called repeatedly, because ALSA's file descriptor is always ready.
According to my research, the bug is in __snd_pcm_dmix_drain(). This function always returns -EAGAIN when SND_PCM_NONBLOCK is set:
if (pcm->mode & SND_PCM_NONBLOCK) return -EAGAIN;
This comes very early in the function, before any other relevant checks. It can never finish that way, and calling it again at any time will never do anything. Thus, snd_pcm_drain() appears to be broken in non-blocking mode.
Or am I misunderstanding how snd_pcm_drain() is supposed to be used in non-blocking mode?
Max
On Thu, 16 Mar 2017 13:23:36 +0100, Max Kellermann wrote:
Hi,
I have received a bug report for the Music Player Daemon which complains about a freezing MPD process, after I switched MPD's ALSA output to non-blocking mode:
https://bugs.musicpd.org/view.php?id=4662
This happens when snd_pcm_drain() is used on a dmix PCM which is in SND_PCM_NONBLOCK mode. snd_pcm_drain() will be called repeatedly, because ALSA's file descriptor is always ready.
According to my research, the bug is in __snd_pcm_dmix_drain(). This function always returns -EAGAIN when SND_PCM_NONBLOCK is set:
if (pcm->mode & SND_PCM_NONBLOCK) return -EAGAIN;
This comes very early in the function, before any other relevant checks. It can never finish that way, and calling it again at any time will never do anything. Thus, snd_pcm_drain() appears to be broken in non-blocking mode.
Or am I misunderstanding how snd_pcm_drain() is supposed to be used in non-blocking mode?
Yeah, the code is obviously wrong. And it seems that now Jaroslav already fixed the issue in git repo. Please give it a try.
thanks,
Takashi
On 2017/03/20 08:38, Takashi Iwai tiwai@suse.de wrote:
Yeah, the code is obviously wrong. And it seems that now Jaroslav already fixed the issue in git repo. Please give it a try.
The bug reporter confirmed that this commit fixes his MPD problem. Thanks.
Max
Dne 16.3.2017 v 13:23 Max Kellermann napsal(a):
Hi,
I have received a bug report for the Music Player Daemon which complains about a freezing MPD process, after I switched MPD's ALSA output to non-blocking mode:
https://bugs.musicpd.org/view.php?id=4662
This happens when snd_pcm_drain() is used on a dmix PCM which is in SND_PCM_NONBLOCK mode. snd_pcm_drain() will be called repeatedly, because ALSA's file descriptor is always ready.
According to my research, the bug is in __snd_pcm_dmix_drain(). This function always returns -EAGAIN when SND_PCM_NONBLOCK is set:
if (pcm->mode & SND_PCM_NONBLOCK) return -EAGAIN;
This comes very early in the function, before any other relevant checks. It can never finish that way, and calling it again at any time will never do anything. Thus, snd_pcm_drain() appears to be broken in non-blocking mode.
Could you test http://git.alsa-project.org/?p=alsa-lib.git;a=commitdiff;h=fdc898d41135b2677... ? There should be a loop with -EAGAIN, but this loop should end when then samples and drained.
Or am I misunderstanding how snd_pcm_drain() is supposed to be used in non-blocking mode?
For non-blocking mode, any calls won't block. So if you like to wait for the completion, you should do a poll/select call or switch the handle to the blocking mode.
Jaroslav
Dne 20.3.2017 v 08:39 Jaroslav Kysela napsal(a):
Dne 16.3.2017 v 13:23 Max Kellermann napsal(a):
Hi,
I have received a bug report for the Music Player Daemon which complains about a freezing MPD process, after I switched MPD's ALSA output to non-blocking mode:
https://bugs.musicpd.org/view.php?id=4662
This happens when snd_pcm_drain() is used on a dmix PCM which is in SND_PCM_NONBLOCK mode. snd_pcm_drain() will be called repeatedly, because ALSA's file descriptor is always ready.
According to my research, the bug is in __snd_pcm_dmix_drain(). This function always returns -EAGAIN when SND_PCM_NONBLOCK is set:
if (pcm->mode & SND_PCM_NONBLOCK) return -EAGAIN;
This comes very early in the function, before any other relevant checks. It can never finish that way, and calling it again at any time will never do anything. Thus, snd_pcm_drain() appears to be broken in non-blocking mode.
Could you test http://git.alsa-project.org/?p=alsa-lib.git;a=commitdiff;h=fdc898d41135b2677... ? There should be a loop with -EAGAIN, but this loop should end when then samples and drained.
Oops. I used wrong handle to check the state. Use commit http://git.alsa-project.org/?p=alsa-lib.git;a=commitdiff;h=e4377b16454f3b7b2... , too.
http://git.alsa-project.org/?p=alsa-lib.git;a=summary
Jaroslav
participants (3)
-
Jaroslav Kysela
-
Max Kellermann
-
Takashi Iwai