audiod: Rewrite status task logic.
authorAndre Noll <maan@systemlinux.org>
Tue, 1 Apr 2008 20:01:28 +0000 (22:01 +0200)
committerAndre Noll <maan@systemlinux.org>
Tue, 1 Apr 2008 20:01:28 +0000 (22:01 +0200)
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
error.h

index d3f45ec..615db84 100644 (file)
--- 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 c2f993d..41ea245 100644 (file)
--- 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 \