Commit 7da0e005 authored by Max Kellermann's avatar Max Kellermann

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.
parent 0eae1c55
......@@ -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);
......
......@@ -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);
}
......
......@@ -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;
......
......@@ -23,6 +23,8 @@
#include "pcm_utils.h"
#include "notify.h"
#include <time.h>
struct audio_output {
/**
* The device's configured display name.
......@@ -51,6 +53,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).
*/
......
......@@ -23,6 +23,12 @@
#include <assert.h>
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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment