From ec4fd9fd88a10bfc88154e8e6791d5d69858a2e5 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 28 Feb 2009 20:43:23 +0100 Subject: 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. --- src/output_control.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/output_control.c') diff --git a/src/output_control.c b/src/output_control.c index 5516af60..c2b7c56d 100644 --- a/src/output_control.c +++ b/src/output_control.c @@ -24,6 +24,12 @@ #include #include +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); -- cgit v1.2.3