shuffle to allow use of execchan in non-pthreads impls

This commit is contained in:
rsc 2004-12-27 17:19:44 +00:00
parent e8a7b96999
commit e127e40bb1
3 changed files with 43 additions and 6 deletions

View file

@ -7,17 +7,22 @@
static Lock thewaitlock;
static Channel *thewaitchan;
static Channel *dowaitchan;
static Channel *execchan;
/* BUG - start waitproc on first exec, not when threadwaitchan is called */
static void
waitproc(void *v)
{
Channel *c;
Waitmsg *w;
Execjob *e;
_threadsetsysproc();
for(;;){
while((w = wait()) == nil){
for(;;){
while((e = nbrecvp(execchan)) != nil)
sendul(e->c, _threadspawn(e->fd, e->cmd, e->argv));
if((w = wait()) != nil)
break;
if(errno == ECHILD)
recvul(dowaitchan);
}
@ -40,15 +45,12 @@ threadwaitchan(void)
}
thewaitchan = chancreate(sizeof(Waitmsg*), 4);
chansetname(thewaitchan, "threadwaitchan");
dowaitchan = chancreate(sizeof(ulong), 1);
chansetname(dowaitchan, "dowaitchan");
proccreate(waitproc, nil, STACK);
unlock(&thewaitlock);
return thewaitchan;
}
int
threadspawn(int fd[3], char *cmd, char *argv[])
_threadspawn(int fd[3], char *cmd, char *argv[])
{
int i, n, p[2], pid;
char exitstr[100];
@ -96,6 +98,24 @@ threadspawn(int fd[3], char *cmd, char *argv[])
return pid;
}
int
threadspawn(int fd[3], char *cmd, char *argv[])
{
if(dowaitchan == nil){
lock(&thewaitlock);
if(dowaitchan == nil){
dowaitchan = chancreate(sizeof(ulong), 1);
chansetname(dowaitchan, "dowaitchan");
execchan = chancreate(sizeof(void*), 0);
chansetname(execchan, "execchan");
proccreate(waitproc, nil, STACK);
}
unlock(&thewaitlock);
}
return _runthreadspawn(fd, cmd, argv);
}
int
_threadexec(Channel *cpid, int fd[3], char *cmd, char *argv[])
{

View file

@ -130,3 +130,9 @@ _pthreadinit(void)
pthread_key_create(&prockey, 0);
}
int
_runthreadspawn(int *fd, char *cmd, char **argv)
{
return _threadspawn(fd, cmd, argv);
}

View file

@ -1,6 +1,7 @@
#include <ucontext.h>
typedef struct Context Context;
typedef struct Execjob Execjob;
typedef struct Proc Proc;
typedef struct _Procrendez _Procrendez;
@ -20,6 +21,14 @@ struct Context
ucontext_t uc;
};
struct Execjob
{
int *fd;
char *cmd;
char **argv;
Channel *c;
};
struct _Thread
{
_Thread *next;
@ -88,3 +97,5 @@ extern void _threadsetproc(Proc*);
extern int _threadlock(Lock*, int, ulong);
extern void _threadunlock(Lock*, ulong);
extern void _pthreadinit(void);
extern int _threadspawn(int*, char*, char**);
extern int _runthreadspawn(int*, char*, char**);