This commit is contained in:
rsc 2006-02-12 16:48:50 +00:00
parent 3fd66761f7
commit 4940b55216
4 changed files with 97 additions and 2 deletions

View file

@ -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

View file

@ -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);

View file

@ -11,6 +11,7 @@ OFILES=\
iorw.$O\
ref.$O\
thread.$O\
wait.$O\
<$PLAN9/src/mksyslib

93
src/libthread/wait.c Normal file
View file

@ -0,0 +1,93 @@
#include <u.h>
#include <libc.h>
#include <thread.h>
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; i<waiting.nmsg; i++){
if(waiting.msg[i]->pid == 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;
}