From 68e0489ae1fe946162d9cedb7767513f2d4ea8d2 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Tue, 1 Apr 2008 22:01:28 +0200 Subject: [PATCH] audiod: Rewrite status task logic. As the status task does not use any file descriptors, it's OK to do everything in one function. So kill status_post_select() and move the code to status_pre_select(). --- audiod.c | 96 ++++++++++++++++++++++++++------------------------------ error.h | 2 ++ 2 files changed, 47 insertions(+), 51 deletions(-) diff --git a/audiod.c b/audiod.c index d3f45ec9..615db847 100644 --- a/audiod.c +++ b/audiod.c @@ -525,8 +525,6 @@ static int check_stat_line(char *line, __a_unused void *data) struct timeval tv = {sec, usec}; compute_time_diff(&tv); } - if (stat_task->clock_diff_count) - stat_task->clock_diff_count--; break; case SI_FORMAT: stat_task->current_audio_format_num = get_audio_format_num( @@ -941,10 +939,6 @@ static void close_stat_pipe(void) status_item_list[SI_BASENAME]); stat_client_write(stat_task->stat_item_values[SI_BASENAME], SI_BASENAME); - if (stat_task->clock_diff_count) { - stat_task->clock_diff_barrier.tv_sec = now->tv_sec + 1; - stat_task->clock_diff_barrier.tv_usec = now->tv_usec; - } } /** @@ -969,76 +963,76 @@ void __noreturn clean_exit(int status, const char *msg) } /* avoid busy loop if server is down */ -static void set_stat_task_restart_barrier(void) +static void set_stat_task_restart_barrier(unsigned seconds) { - struct timeval delay = {5, 0}; + struct timeval delay = {seconds, 0}; tv_add(now, &delay, &stat_task->restart_barrier); } /* restart the client task if necessary */ -static void status_pre_select(struct sched *s, struct task *t) +static void status_pre_select(__a_unused struct sched *s, struct task *t) { struct status_task *st = container_of(t, struct status_task, task); - int ret; - if (st->ct || audiod_status == AUDIOD_OFF) /* no need to restart */ + if (audiod_status == AUDIOD_OFF) { + if (!st->ct) + return; + if (st->ct->task.error >= 0) { + st->ct->task.error = -E_AUDIOD_OFF; + return; + } + if (st->ct->task.error != -E_TASK_UNREGISTERED) + return; + close_stat_pipe(); + st->clock_diff_count = conf.clock_diff_count_arg; + return; + } + if (st->ct) { + unsigned bytes_left; + if (st->ct->task.error < 0) { + if (st->ct->task.error != -E_TASK_UNREGISTERED) + return; + close_stat_pipe(); + return; + } + if (st->ct->status != CL_RECEIVING) + return; + bytes_left = for_each_line(st->ct->buf, st->ct->loaded, + &check_stat_line, NULL); + if (st->ct->loaded != bytes_left) { + st->last_status_read = *now; + st->ct->loaded = bytes_left; + } else { + struct timeval diff; + tv_diff(now, &st->last_status_read, &diff); + if (diff.tv_sec > 61) + st->ct->task.error = -E_STATUS_TIMEOUT; + } return; - if (!st->clock_diff_count && tv_diff(now, &st->restart_barrier, NULL) - < 0) + } + if (tv_diff(now, &st->restart_barrier, NULL) < 0) return; if (st->clock_diff_count) { /* get status only one time */ char *argv[] = {"audiod", "stat", "1", NULL}; int argc = 3; - if (tv_diff(now, &st->clock_diff_barrier, NULL) < 0) - return; PARA_INFO_LOG("clock diff count: %d\n", st->clock_diff_count); - ret = client_open(argc, argv, &st->ct); + st->clock_diff_count--; + client_open(argc, argv, &st->ct); + set_stat_task_restart_barrier(2); } else { char *argv[] = {"audiod", "stat", NULL}; int argc = 2; - ret = client_open(argc, argv, &st->ct); - } - set_stat_task_restart_barrier(); - if (ret < 0) - return; - s->timeout.tv_sec = 0; - s->timeout.tv_usec = 1; -} - -static void status_post_select(__a_unused struct sched *s, struct task *t) -{ - struct status_task *st = container_of(t, struct status_task, task); - unsigned bytes_left; - - if (!st->ct || st->ct->status != CL_RECEIVING) - return; - if (audiod_status == AUDIOD_OFF || st->ct->task.error < 0) { - if (st->ct->task.error >= 0) - unregister_task(&st->ct->task); - if (audiod_status == AUDIOD_OFF) - st->clock_diff_count = conf.clock_diff_count_arg; - close_stat_pipe(); - return; - } - bytes_left = for_each_line(st->ct->buf, st->ct->loaded, - &check_stat_line, NULL); - if (st->ct->loaded != bytes_left) { - st->last_status_read = *now; - st->ct->loaded = bytes_left; - } else { - struct timeval diff; - tv_diff(now, &st->last_status_read, &diff); - if (diff.tv_sec > 61) - close_stat_pipe(); + client_open(argc, argv, &st->ct); + set_stat_task_restart_barrier(5); } + st->last_status_read = *now; } static void init_status_task(struct status_task *st) { memset(st, 0, sizeof(struct status_task)); st->task.pre_select = status_pre_select; - st->task.post_select = status_post_select; st->sa_time_diff_sign = 1; st->clock_diff_count = conf.clock_diff_count_arg; st->current_audio_format_num = -1; diff --git a/error.h b/error.h index c2f993d0..41ea2459 100644 --- a/error.h +++ b/error.h @@ -209,6 +209,8 @@ extern const char **para_errlist[]; PARA_ERROR(MISSING_COLON, "syntax error: missing colon"), \ PARA_ERROR(UNSUPPORTED_AUDIO_FORMAT, "given audio format not supported"), \ PARA_ERROR(NOT_PLAYING, "not playing"), \ + PARA_ERROR(AUDIOD_OFF, "audiod switched off"), \ + PARA_ERROR(STATUS_TIMEOUT, "timeout reading server status"), \ #define AUDIOD_COMMAND_ERRORS \ -- 2.39.2