audiod: fix mode cycling
authorAndre Noll <maan@systemlinux.org>
Mon, 5 Feb 2007 20:29:02 +0000 (21:29 +0100)
committerAndre Noll <maan@systemlinux.org>
Mon, 5 Feb 2007 20:29:02 +0000 (21:29 +0100)
This was quite buggy all the time, but wasn't noticed due to the typo bug
which was fixed in 1b46ae4193cddb7d589b0f2f7d8158b84f7e9f6d.

Now, the status task no longer has an event handler as both its pre_select
and its post_select functions always succeed and the status task is supposed
to never terminate. Unlike the client task whose event handler now does all
the cleanup if the connection to para_server breaks down for whatever reason.

audiod.c

index 8eb425d..5aa32de 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -981,33 +981,27 @@ static void init_command_task(struct command_task *ct)
 static void client_task_event_handler(__a_unused struct task *t)
 {
        struct private_client_data *pcd = t->private_data;
+       int i;
+       struct timeval delay = {1, 0};
+
        if (t->ret == -E_HANDSHAKE_COMPLETE)
                return;
        unregister_task(t);
-       pcd->eof = 1;
-}
-
-static void status_event_handler(__a_unused struct task *t)
-{
-       struct timeval delay = {1, 0};
-       int i;
-       struct status_task *st = t->private_data;
-
-       PARA_ERROR_LOG("%s\n", PARA_STRERROR(-t->ret));
        close_stat_pipe();
+       if (t->ret != -E_SERVER_EOF)
+               stat_task->clock_diff_count = conf.clock_diff_count_arg;
        /* avoid busy loop if server is down */
-       tv_add(now, &delay, &st->restart_barrier);
+       tv_add(now, &delay, &stat_task->restart_barrier);
        FOR_EACH_AUDIO_FORMAT(i)
-               afi[i].restart_barrier = st->restart_barrier;
+               afi[i].restart_barrier = stat_task->restart_barrier;
 }
 
 static void status_pre_select(struct sched *s, struct task *t)
 {
        struct status_task *st = t->private_data;
+       int ret;
 
-       t->ret = 1;
-       if (st->pcd && (audiod_status == AUDIOD_OFF || st->pcd->eof))
-               close_stat_pipe();
+       t->ret = 1; /* always successful */
        if (st->pcd || audiod_status == AUDIOD_OFF)
                return;
        if (!st->clock_diff_count && tv_diff(now, &st->restart_barrier, NULL)
@@ -1019,15 +1013,14 @@ static void status_pre_select(struct sched *s, struct task *t)
                if (tv_diff(now, &st->clock_diff_barrier, NULL) < 0)
                        return;
                PARA_INFO_LOG("clock diff count: %d\n", st->clock_diff_count);
-               t->ret = client_open(argc, argv, &st->pcd);
+               ret = client_open(argc, argv, &st->pcd);
 
        } else {
                char *argv[] = {"audiod", "stat", NULL};
                int argc = 2;
-               t->ret = client_open(argc, argv, &st->pcd);
+               ret = client_open(argc, argv, &st->pcd);
        }
-
-       if (t->ret < 0)
+       if (ret < 0)
                return;
        st->pcd->task.event_handler = client_task_event_handler;
        s->timeout.tv_sec = 0;
@@ -1042,6 +1035,12 @@ static void status_post_select(__a_unused struct sched *s, struct task *t)
        t->ret = 1;
        if (!st->pcd || st->pcd->status != CL_RECEIVING)
                return;
+       if (st->pcd && audiod_status == AUDIOD_OFF) {
+               unregister_task(&st->pcd->task);
+               close_stat_pipe();
+               st->clock_diff_count = conf.clock_diff_count_arg;
+               return;
+       }
        bytes_left = for_each_line(st->pcd->buf, st->pcd->loaded,
                &check_stat_line);
        if (st->pcd->loaded != bytes_left) {
@@ -1060,7 +1059,6 @@ 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->task.event_handler = status_event_handler;
        st->task.private_data = st;
        st->sa_time_diff_sign = 1;
        st->clock_diff_count = conf.clock_diff_count_arg;