audiod: Handle crashes of para_server more robustly.
authorAndre Noll <maan@systemlinux.org>
Sun, 10 Oct 2010 19:32:58 +0000 (21:32 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 10 Oct 2010 19:32:58 +0000 (21:32 +0200)
In case para_server dies unexpectedly, para_audiod may still have a partial status
item in the buffer tree node of the client task which can lead to a busy loop.

Fix this by flushing the input queue and invalidate the current audio format to prevent
recreating a buffer tree before the status task resumes.

There is already flush_input_queue() in buffer_tree.c but that can't be called by audiod.c
as it is a static function. Make it public and rename it to btr_drain() which is shorter and
more to the point and has the usual btr_ prefix.

audiod.c
buffer_tree.c
buffer_tree.h

index 668b0f7..89b160d 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -1222,6 +1222,8 @@ static void status_post_select(__a_unused struct sched *s, struct task *t)
                        st->min_iqs = sz + 1;
                goto out;
        }
+       btr_drain(st->btrn);
+       st->current_audio_format_num = -1;
        if (tv_diff(now, &st->restart_barrier, NULL) < 0)
                goto out;
        if (st->clock_diff_count) { /* get status only one time */
index 3f1cc71..bdcbec8 100644 (file)
@@ -660,9 +660,10 @@ void btr_consume(struct btr_node *btrn, size_t numbytes)
        return btr_consume(btrn, sz);
 }
 
-static void flush_input_queue(struct btr_node *btrn)
+void btr_drain(struct btr_node *btrn)
 {
        struct btr_buffer_reference *br, *tmp;
+
        FOR_EACH_BUFFER_REF_SAFE(br, tmp, btrn)
                btr_drop_buffer_reference(br);
 }
@@ -702,7 +703,7 @@ void btr_remove_node(struct btr_node *btrn)
        PARA_NOTICE_LOG("removing btr node %s from buffer tree\n", btrn->name);
        FOR_EACH_CHILD(ch, btrn)
                ch->parent = NULL;
-       flush_input_queue(btrn);
+       btr_drain(btrn);
        if (btrn->parent)
                list_del(&btrn->node);
 }
index 549f95a..8bc8e60 100644 (file)
@@ -202,3 +202,4 @@ int btr_node_status(struct btr_node *btrn, size_t min_iqs,
                enum btr_node_type type);
 void btr_get_node_start(struct btr_node *btrn, struct timeval *tv);
 struct btr_node *btr_search_node(const char *name, struct btr_node *root);
+void btr_drain(struct btr_node *btrn);