add wait
This commit is contained in:
parent
3fd66761f7
commit
4940b55216
4 changed files with 97 additions and 2 deletions
|
|
@ -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
|
or to Linux-sparc64-swapcontext.c. Those are functions from
|
||||||
the GNU C library and are provided for systems that use the GNU C
|
the GNU C library and are provided for systems that use the GNU C
|
||||||
library but somehow are missing those functions. They are
|
library but somehow are missing those functions. They are
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,8 @@ _threadspawn(int fd[3], char *cmd, char *argv[])
|
||||||
close(p[1]);
|
close(p[1]);
|
||||||
return -1;
|
return -1;
|
||||||
case 0:
|
case 0:
|
||||||
rfork(RFNOTEG);
|
/* can't RFNOTEG - will lose tty */
|
||||||
|
/* rfork(RFNOTEG); */
|
||||||
dup2(fd[0], 0);
|
dup2(fd[0], 0);
|
||||||
dup2(fd[1], 1);
|
dup2(fd[1], 1);
|
||||||
dup2(fd[2], 2);
|
dup2(fd[2], 2);
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ OFILES=\
|
||||||
iorw.$O\
|
iorw.$O\
|
||||||
ref.$O\
|
ref.$O\
|
||||||
thread.$O\
|
thread.$O\
|
||||||
|
wait.$O\
|
||||||
|
|
||||||
<$PLAN9/src/mksyslib
|
<$PLAN9/src/mksyslib
|
||||||
|
|
||||||
|
|
|
||||||
93
src/libthread/wait.c
Normal file
93
src/libthread/wait.c
Normal 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;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue