From 1c465cd2393fb9c72e2bc794c93c0b9eb74dd5de Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Fri, 22 Oct 2010 07:46:17 +0200 Subject: [PATCH] When the end of a stream is reached (ie mix_eof() called) other possibly blocked streams are processed. If during this phase the end of another stream is reached then stop the processing because the job will be already finished by the second stream. Otherwise we may end up running a destroyed stream. help from Edward Wandasiewicz , thanks --- aucat/aproc.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/aucat/aproc.c b/aucat/aproc.c index 0b25d62..7c30a2c 100644 --- a/aucat/aproc.c +++ b/aucat/aproc.c @@ -911,7 +911,7 @@ mix_out(struct aproc *p, struct abuf *obuf) void mix_eof(struct aproc *p, struct abuf *ibuf) { - struct abuf *i, *inext, *obuf = LIST_FIRST(&p->outs); + struct abuf *i, *obuf = LIST_FIRST(&p->outs); unsigned odone; mix_setmaster(p); @@ -927,10 +927,13 @@ mix_eof(struct aproc *p, struct abuf *ibuf) * Find a blocked input. */ odone = obuf->len; - for (i = LIST_FIRST(&p->ins); i != NULL; i = inext) { - inext = LIST_NEXT(i, ient); + LIST_FOREACH(i, &p->ins, ient) { + /* + * abuf_fill() may trigger mix_eof(), do the job + * and possibly reorder the list + */ if (!abuf_fill(i)) - continue; + return; if (MIX_ROK(i) && i->r.mix.done < obuf->w.mix.todo) { abuf_run(i); return; @@ -1352,7 +1355,7 @@ sub_eof(struct aproc *p, struct abuf *ibuf) void sub_hup(struct aproc *p, struct abuf *obuf) { - struct abuf *i, *inext, *ibuf = LIST_FIRST(&p->ins); + struct abuf *i, *ibuf = LIST_FIRST(&p->ins); unsigned idone; if (!aproc_inuse(p)) { @@ -1366,10 +1369,13 @@ sub_hup(struct aproc *p, struct abuf *obuf) * Find a blocked output. */ idone = ibuf->len; - for (i = LIST_FIRST(&p->outs); i != NULL; i = inext) { - inext = LIST_NEXT(i, oent); + LIST_FOREACH(i, &p->outs, oent) { + /* + * abuf_flush() may trigger sub_hup(), do the job + * and possibly reorder the list + */ if (!abuf_flush(i)) - continue; + return; if (SUB_WOK(i) && i->w.sub.done < ibuf->used) { abuf_run(i); return;