123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- #include <u.h>
- #include <libc.h>
- #include <thread.h>
- #include <fcall.h>
- #include "playlist.h"
- static Channel *reqs;
- Req*
- reqalloc(void)
- {
- Req *r;
- if(reqs == nil)
- reqs = chancreate(sizeof(Req*), 256);
- if(r = nbrecvp(reqs))
- return r;
- r = malloc(sizeof(Req));
- return r;
- }
- void
- reqfree(Req *r)
- {
- if(!nbsendp(reqs, r))
- free(r);
- }
- Wmsg
- waitmsg(Worker *w, Channel *q)
- {
- Wmsg m;
- sendp(q, w);
- recv(w->eventc, &m);
- return m;
- }
- int
- sendmsg(Channel *q, Wmsg *m)
- {
- Worker *w;
- 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, marker;
- void *a;
- a = m->arg;
- /*
- * 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
- */
- marker.eventc = nil; /* Only markers have 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);
- m->arg = nil;
- }
- void
- readbuf(Req *r, void *s, long n)
- {
- r->ofcall.count = r->ifcall.count;
- if(r->ifcall.offset >= n){
- r->ofcall.count = 0;
- return;
- }
- if(r->ifcall.offset+r->ofcall.count > n)
- r->ofcall.count = n - r->ifcall.offset;
- memmove(r->ofcall.data, (char*)s+r->ifcall.offset, r->ofcall.count);
- }
- void
- readstr(Req *r, char *s)
- {
- readbuf(r, s, strlen(s));
- }
|