aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2008-09-09 09:03:08 +0200
committerMax Kellermann <max@duempel.org>2008-09-09 09:03:08 +0200
commit5c81b716e21146a59d6636fcff3b0dc5687a5760 (patch)
tree54efa4ae2046e793fb12253ab97fbe109157bfcc
parent37489b1f97ecd1a2d72106b497f9c7cda92a48c0 (diff)
downloadmpd-5c81b716e21146a59d6636fcff3b0dc5687a5760.tar.gz
mpd-5c81b716e21146a59d6636fcff3b0dc5687a5760.tar.xz
mpd-5c81b716e21146a59d6636fcff3b0dc5687a5760.zip
alsa: use blocking instead of non-blocking write
The way we used non-blocking mode was HORRIBLE. It was non-blocking to ALSA, but we end up blocking in a busy loop that does absolutely NOTHING but retry. We don't check for playback cancellation (like we do in decoders) or anything. This is seriously broken and I can imagine it affects people on fast CPUs more because we do asynchronous output buffering and our ALSA device will always have data ready.
-rw-r--r--src/audioOutputs/audioOutput_alsa.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/src/audioOutputs/audioOutput_alsa.c b/src/audioOutputs/audioOutput_alsa.c
index 065bcff39..8149917c4 100644
--- a/src/audioOutputs/audioOutput_alsa.c
+++ b/src/audioOutputs/audioOutput_alsa.c
@@ -37,6 +37,9 @@ static const char default_device[] = "default";
#include <alsa/asoundlib.h>
+/* #define MPD_SND_PCM_NONBLOCK SND_PCM_NONBLOCK */
+#define MPD_SND_PCM_NONBLOCK 0
+
typedef snd_pcm_sframes_t alsa_writei_t(snd_pcm_t * pcm, const void *buffer,
snd_pcm_uframes_t size);
@@ -157,16 +160,18 @@ static int alsa_openDevice(struct audio_output *audioOutput)
ad->device, audioFormat->bits);
err = snd_pcm_open(&ad->pcmHandle, ad->device,
- SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
+ SND_PCM_STREAM_PLAYBACK, MPD_SND_PCM_NONBLOCK);
if (err < 0) {
ad->pcmHandle = NULL;
goto error;
}
+#if MPD_SND_PCM_NONBLOCK == SND_PCM_NONBLOCK
cmd = "snd_pcm_nonblock";
err = snd_pcm_nonblock(ad->pcmHandle, 0);
if (err < 0)
goto error;
+#endif /* MPD_SND_PCM_NONBLOCK == SND_PCM_NONBLOCK */
period_time_ro = period_time = ad->period_time;
configure_hw: