commit 4940b55216d170189ddc4c3ba9fe8b2b0fb507a0 from: rsc date: Sun Feb 12 16:48:50 2006 UTC add wait commit - 3fd66761f7d3b1b93e9d2f819b7edbdb13152c75 commit + 4940b55216d170189ddc4c3ba9fe8b2b0fb507a0 blob - 960a9a77b9c593f6891a3e413f7b8ecc6426e304 blob + f4ee354e94347f79787957d81a0db4bff135c7ea --- src/libthread/COPYRIGHT +++ src/libthread/COPYRIGHT @@ -45,7 +45,7 @@ Contains parts of an earlier library that has: === -The above notice does *NOT* apply to Linux-sparc64-context.S +The above notices do *NOT* apply to Linux-sparc64-context.S or to Linux-sparc64-swapcontext.c. Those are functions from the GNU C library and are provided for systems that use the GNU C library but somehow are missing those functions. They are blob - bfd4f71860f36a13894351aca8a4e1f0ef4cd471 blob + d745248824f4c9a9051637520361866ec5617c8a --- src/libthread/exec.c +++ src/libthread/exec.c @@ -75,7 +75,8 @@ _threadspawn(int fd[3], char *cmd, char *argv[]) close(p[1]); return -1; case 0: - rfork(RFNOTEG); + /* can't RFNOTEG - will lose tty */ + /* rfork(RFNOTEG); */ dup2(fd[0], 0); dup2(fd[1], 1); dup2(fd[2], 2); blob - 0b6205655e2099da1f39aafb84138097de359cbc blob + d552d0794e499b7672a7749669462d1493432908 --- src/libthread/mkfile +++ src/libthread/mkfile @@ -11,6 +11,7 @@ OFILES=\ iorw.$O\ ref.$O\ thread.$O\ + wait.$O\ <$PLAN9/src/mksyslib blob - /dev/null blob + 24538e586da3569638eac9b38833edd65ba05fea (mode 644) --- /dev/null +++ src/libthread/wait.c @@ -0,0 +1,93 @@ +#include +#include +#include + +typedef struct Waiter Waiter; + +struct { + QLock lk; + Waitmsg **msg; + int nmsg; + int muxer; + Waiter *head; +} waiting; + +struct Waiter +{ + Rendez r; + Waitmsg *msg; + int pid; + Waiter *next; + Waiter *prev; +}; + +/* see src/libmux/mux.c */ +Waitmsg* +procwait(int pid) +{ + Waiter *w; + Waiter me; + Waitmsg *msg; + int i; + + memset(&me, 0, sizeof me); + me.pid = pid; + me.r.l = &waiting.lk; + + qlock(&waiting.lk); + for(i=0; ipid == pid){ + msg = waiting.msg[i]; + waiting.msg[i] = waiting.msg[--waiting.nmsg]; + qunlock(&waiting.lk); + return msg; + } + } + me.next = waiting.head; + me.prev = nil; + if(me.next) + me.next->prev = &me; + waiting.head = &me; + while(waiting.muxer && me.msg==nil) + rsleep(&me.r); + + if(!me.msg){ + if(waiting.muxer) + abort(); + waiting.muxer = 1; + while(!me.msg){ + qunlock(&waiting.lk); + msg = recvp(threadwaitchan()); + qlock(&waiting.lk); + if(msg == nil) /* shouldn't happen */ + break; + for(w=waiting.head; w; w=w->next) + if(w->pid == msg->pid) + break; + if(w){ + if(w->prev) + w->prev->next = w->next; + else + waiting.head = w->next; + if(w->next) + w->next->prev = w->prev; + me.msg = msg; + rwakeup(&w->r); + }else{ + waiting.msg = realloc(waiting.msg, (waiting.nmsg+1)*sizeof waiting.msg[0]); + if(waiting.msg == nil) + sysfatal("out of memory"); + waiting.msg[waiting.nmsg++] = msg; + } + } + waiting.muxer = 0; + if(waiting.head) + rwakeup(&waiting.head->r); + } + qunlock(&waiting.lk); + if (me.msg->pid < 0) { + free(me.msg); + me.msg = 0; + } + return me.msg; +}