From 7da0e005f34bd8ce305b8ece7a33a8405bbaba87 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 29 Oct 2008 22:32:50 +0100 Subject: output: delay reopen after device failure When one of several output devices failed, MPD tried to reopen it quite often, wasting a lot of resources. This patch adds a delay: wait 10 seconds before retrying. This might be changed to exponential delays later, but for now, it makes the problem go away. --- src/audio.c | 1 + src/output_control.c | 9 ++++++--- src/output_init.c | 1 + src/output_internal.h | 8 ++++++++ src/output_thread.c | 8 ++++++++ 5 files changed, 24 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/audio.c b/src/audio.c index 3d4cf1a4..45f36fff 100644 --- a/src/audio.c +++ b/src/audio.c @@ -342,6 +342,7 @@ int enableAudioDevice(unsigned int device) if (device >= audioOutputArraySize) return -1; + audioOutputArray[device].reopen_after = 0; audioOutputArray[device].enabled = true; idle_add(IDLE_OUTPUT); diff --git a/src/output_control.c b/src/output_control.c index 142ac765..c4c9510d 100644 --- a/src/output_control.c +++ b/src/output_control.c @@ -57,6 +57,8 @@ audio_output_open(struct audio_output *audioOutput, { bool ret = true; + audioOutput->reopen_after = 0; + if (audioOutput->open && audio_format_equals(audioFormat, &audioOutput->inAudioFormat)) { return true; @@ -93,9 +95,10 @@ void audio_output_update(struct audio_output *ao, const struct audio_format *audio_format) { - if (ao->enabled) - audio_output_open(ao, audio_format); - else if (audio_output_is_open(ao)) + if (ao->enabled) { + if (ao->reopen_after == 0 || time(NULL) > ao->reopen_after) + audio_output_open(ao, audio_format); + } else if (audio_output_is_open(ao)) audio_output_close(ao); } diff --git a/src/output_init.c b/src/output_init.c index 9393e295..89853ff9 100644 --- a/src/output_init.c +++ b/src/output_init.c @@ -87,6 +87,7 @@ int audio_output_init(struct audio_output *ao, ConfigParam * param) ao->plugin = plugin; ao->enabled = true; ao->open = false; + ao->reopen_after = 0; ao->convBuffer = NULL; ao->convBufferLen = 0; diff --git a/src/output_internal.h b/src/output_internal.h index 0fae6f30..cfa23121 100644 --- a/src/output_internal.h +++ b/src/output_internal.h @@ -23,6 +23,8 @@ #include "pcm_utils.h" #include "notify.h" +#include + struct audio_output { /** * The device's configured display name. @@ -50,6 +52,12 @@ struct audio_output { */ bool open; + /** + * If not zero, the device has failed, and should not be + * reopened automatically before this time stamp. + */ + time_t reopen_after; + /** * The audio_format in which audio data is received from the * player thread (which in turn receives it from the decoder). diff --git a/src/output_thread.c b/src/output_thread.c index 28a575a1..5d468c57 100644 --- a/src/output_thread.c +++ b/src/output_thread.c @@ -23,6 +23,12 @@ #include +enum { + /** after a failure, wait this number of seconds before + automatically reopening the device */ + REOPEN_AFTER = 10, +}; + static void ao_command_finished(struct audio_output *ao) { assert(ao->command != AO_COMMAND_NONE); @@ -104,6 +110,8 @@ static void *audio_output_task(void *arg) assert(!ao->open); if (ao->result == true) ao->open = true; + else + ao->reopen_after = time(NULL) + REOPEN_AFTER; ao_command_finished(ao); break; -- cgit v1.2.3