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.
st->min_iqs = sz + 1;
goto out;
}
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 */
if (tv_diff(now, &st->restart_barrier, NULL) < 0)
goto out;
if (st->clock_diff_count) { /* get status only one time */
return btr_consume(btrn, sz);
}
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;
{
struct btr_buffer_reference *br, *tmp;
FOR_EACH_BUFFER_REF_SAFE(br, tmp, btrn)
btr_drop_buffer_reference(br);
}
FOR_EACH_BUFFER_REF_SAFE(br, tmp, btrn)
btr_drop_buffer_reference(br);
}
PARA_NOTICE_LOG("removing btr node %s from buffer tree\n", btrn->name);
FOR_EACH_CHILD(ch, btrn)
ch->parent = NULL;
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);
if (btrn->parent)
list_del(&btrn->node);
}
if (btrn->parent)
list_del(&btrn->node);
}
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);
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);