- [rsc] --rw-rw-r-- M 451989 sape sys 1547 Nov 6 11:09 sys/src/games/music/playlistfs/boilerplate.c /n/sourcesdump/2005/1106/plan9/sys/src/games/music/playlistfs/boilerplate.c:41,73 - /n/sourcesdump/2005/1107/plan9/sys/src/games/music/playlistfs/boilerplate.c:41,82 { Worker *w; - if(w = nbrecvp(q)) - send(w->eventc, m); - return w != nil; + while(w = nbrecvp(q)){ + /* Test for markerdom (see bcastmsg) */ + if(w->eventc){ + send(w->eventc, m); + return 1; + } + sendp(q, w); /* put back */ + } + return 0; } void bcastmsg(Channel *q, Wmsg *m) { - Worker *w; - Channel *c; + Worker *w, marker; void *a; a = m->arg; /* - * Allocate a temp chan to prevent workers from getting the - * broadcast and putting themselves back on the workers + * Use a marker to mark the end of the queue. + * This prevents workers from getting the + * broadcast and putting themselves back on the * queue before the broadcast has finished */ - c = chancreate(sizeof(Worker*), 256); - while(w = nbrecvp(q)) - sendp(c, w); - while(w = nbrecvp(c)){ - if(a) m->arg = strdup(a); - send(w->eventc, m); + marker.eventc = nil; + sendp(q, &marker); + while((w = recvp(q)) != &marker){ + if(w->eventc == nil){ + /* somebody else's marker, put it back */ + sendp(q, w); + }else{ + if(a) m->arg = strdup(a); + send(w->eventc, m); + } } free(a); - chanfree(c); m->arg = nil; }