From: Andre Noll Date: Thu, 3 Feb 2011 16:15:27 +0000 (+0100) Subject: libao: Avoid segfault on com_cycle. X-Git-Tag: v0.4.7~10 X-Git-Url: http://git.tue.mpg.de/?a=commitdiff_plain;h=cf66f48eb13a66f1d89d612be3ad8f950ece5816;p=paraslash.git libao: Avoid segfault on com_cycle. Executing the cycle command while the ao writer is active can lead to a segmentation fault because kill_all_decoders() removes the buffer tree node of the ao writer but leaves its child node alive. This patch changes kill_all_decoders() to kill the receiver node only while leaving all other nodes alone, removing the assumption that the set of filter nodes and writer nodes are the only nodes in the buffer tree. This assumption used to be true but became false with the merge of the ao writer which has two buffer tree nodes. It is enough to kill only the receiver node as all other nodes will eventually notice that their parent node no longer exists and exit shortly thereafter. --- diff --git a/audiod.c b/audiod.c index 9f664e17..6a4c9dbe 100644 --- a/audiod.c +++ b/audiod.c @@ -429,22 +429,15 @@ static void kill_btrn(struct btr_node *btrn, struct task *t, int error) static void kill_all_decoders(int error) { - int i, j; + int i; FOR_EACH_SLOT(i) { - struct slot_info *s = &slot[i]; - struct audio_format_info *a; + struct slot_info *s = slot + i; if (s->format < 0) continue; - a = afi + s->format; - if (s->wns) - for (j = 0; j < a->num_writers; j++) - kill_btrn(s->wns[j].btrn, &s->wns[j].task, error); - if (s->fns) - for (j = 0; j < a->num_writers; j++) - kill_btrn(s->fns[j].btrn, &s->wns[j].task, error); - if (s->receiver_node) - kill_btrn(s->receiver_node->btrn, &s->receiver_node->task, + if (!s->receiver_node) + continue; + kill_btrn(s->receiver_node->btrn, &s->receiver_node->task, error); } }