From: Andre Noll Date: Tue, 12 Jan 2010 23:23:54 +0000 (+0100) Subject: audiod: Make mode switching (on, off, sb) work again. X-Git-Tag: v0.4.2~130 X-Git-Url: http://git.tue.mpg.de/?a=commitdiff_plain;h=c057c50d3d6e4c8d61e9c6db3e120270793e270e;p=paraslash.git audiod: Make mode switching (on, off, sb) work again. It is not sufficient to set the task status to an error value. We also have to remove the btr node from the buffer tree. --- diff --git a/audiod.c b/audiod.c index 128f7b42..2819091b 100644 --- a/audiod.c +++ b/audiod.c @@ -389,6 +389,20 @@ static void close_filters(struct slot_info *s) s->fns = NULL; } +/* + * Whenever a task commits suicide by returning from post_select with t->error + * < 0, it also removes its btr node. We do exactly that to kill a running + * task. Note that the scheduler checks t->error also _before_ each pre/post + * select call, so the victim will never be scheduled again. + */ +static void kill_btrn(struct btr_node *btrn, struct task *t, int error) +{ + if (t->error < 0) + return; + t->error = error; + btr_remove_node(btrn); +} + static void kill_all_decoders(int error) { int i, j; @@ -401,12 +415,13 @@ static void kill_all_decoders(int error) a = afi + s->format; if (s->wns) for (j = 0; j < a->num_writers; j++) - s->wns[j].task.error = error; + kill_btrn(s->wns[j].btrn, &s->wns[j].task, error); if (s->fns) for (j = 0; j < a->num_writers; j++) - s->fns[j].task.error = error; + kill_btrn(s->fns[j].btrn, &s->wns[j].task, error); if (s->receiver_node) - s->receiver_node->task.error = error; + kill_btrn(s->receiver_node->btrn, &s->receiver_node->task, + error); } } @@ -1091,9 +1106,9 @@ static void start_stop_decoders(struct sched *s) FOR_EACH_SLOT(i) if (try_to_close_slot(i)) sched_min_delay(s); -// if (audiod_status != AUDIOD_ON || -// !(stat_task->vss_status & VSS_STATUS_FLAG_PLAYING)) -// return kill_all_decoders(-E_NOT_PLAYING); + if (audiod_status != AUDIOD_ON || + !(stat_task->vss_status & VSS_STATUS_FLAG_PLAYING)) + return kill_all_decoders(-E_NOT_PLAYING); ret = open_current_receiver(s); if (ret < 0) return;