diff options
author | Max Kellermann <max@duempel.org> | 2009-02-28 20:43:23 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-02-28 20:43:23 +0100 |
commit | ec4fd9fd88a10bfc88154e8e6791d5d69858a2e5 (patch) | |
tree | c98fe447adcafe85ba9ee94d93d98377f9ffdaeb /src/output_control.c | |
parent | a5c09c91c414ba08d915331797e717334ac06456 (diff) | |
download | mpd-ec4fd9fd88a10bfc88154e8e6791d5d69858a2e5.tar.gz mpd-ec4fd9fd88a10bfc88154e8e6791d5d69858a2e5.tar.xz mpd-ec4fd9fd88a10bfc88154e8e6791d5d69858a2e5.zip |
output: use GTimer instead of time_t for reopen after failure
time() is not a monotonic timer, and MPD might get confused by clock
skews. clock_gettime() provides a monotonic clock, but is not
portable to non-POSIX systems (i.e. Windows). This patch uses GLib's
GTimer API, which aims to be portable.
Diffstat (limited to 'src/output_control.c')
-rw-r--r-- | src/output_control.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/src/output_control.c b/src/output_control.c index 5516af607..c2b7c56d4 100644 --- a/src/output_control.c +++ b/src/output_control.c @@ -24,6 +24,12 @@ #include <assert.h> #include <stdlib.h> +enum { + /** after a failure, wait this number of seconds before + automatically reopening the device */ + REOPEN_AFTER = 10, +}; + struct notify audio_output_client_notify; static void ao_command_wait(struct audio_output *ao) @@ -53,7 +59,10 @@ bool audio_output_open(struct audio_output *ao, const struct audio_format *audio_format) { - ao->reopen_after = 0; + if (ao->fail_timer != NULL) { + g_timer_destroy(ao->fail_timer); + ao->fail_timer = NULL; + } if (ao->open && audio_format_equals(audio_format, &ao->in_audio_format)) { @@ -90,7 +99,8 @@ audio_output_update(struct audio_output *ao, const struct audio_format *audio_format) { if (ao->enabled) { - if (ao->reopen_after == 0 || time(NULL) > ao->reopen_after) + if (ao->fail_timer == NULL || + g_timer_elapsed(ao->fail_timer, NULL) > REOPEN_AFTER) audio_output_open(ao, audio_format); } else if (audio_output_is_open(ao)) audio_output_close(ao); @@ -127,14 +137,22 @@ void audio_output_cancel(struct audio_output *ao) void audio_output_close(struct audio_output *ao) { + assert(!ao->open || ao->fail_timer == NULL); + if (ao->open) ao_command(ao, AO_COMMAND_CLOSE); + else if (ao->fail_timer != NULL) { + g_timer_destroy(ao->fail_timer); + ao->fail_timer = NULL; + } } void audio_output_finish(struct audio_output *ao) { audio_output_close(ao); + assert(ao->fail_timer == NULL); + if (ao->thread != NULL) { ao_command(ao, AO_COMMAND_KILL); g_thread_join(ao->thread); |