output/alsa: check PCM state before calling snd_pcm_drain()

Apparently, if snd_pcm_drain() returns EAGAIN, it does not actually
want to be called again; the next call will snd_pcm_drain() will also
return EAGAIN, forever, even though the PCM state has meanwhile
switched to SND_PCM_STATE_SETUP.  This causes a busy loop; to fix
this, we should always check snd_pcm_state() to see if draining is
really required.
This commit is contained in:
Max Kellermann 2019-06-28 08:55:23 +02:00
parent 8bf3f9b874
commit 543776d9c9
2 changed files with 19 additions and 0 deletions

1
NEWS
View File

@ -4,6 +4,7 @@ ver 0.21.11 (not yet released)
* decoder
- wildmidi: log error if library initialization fails
* output
- alsa: fix busy loop while draining
- alsa, osx: fix distortions with DSD_U32 and DoP on 32 bit CPUs
* protocol
- fix "list" with multiple "group" levels

View File

@ -774,6 +774,24 @@ AlsaOutput::DrainInternal()
don't need to drain it */
return true;
switch (snd_pcm_state(pcm)) {
case SND_PCM_STATE_PREPARED:
case SND_PCM_STATE_RUNNING:
/* these states require a call to snd_pcm_drain() */
break;
case SND_PCM_STATE_DRAINING:
/* already draining, but not yet finished; this is
probably a spurious epoll event, and we should wait
for the next one */
return false;
default:
/* all other states cannot be drained, and we're
done */
return true;
}
/* .. and finally drain the ALSA hardware buffer */
int result;