diff options
-rw-r--r-- | src/libthread/exec.c | 32 | ||||
-rw-r--r-- | src/libthread/pthread.c | 6 | ||||
-rw-r--r-- | src/libthread/threadimpl.h | 11 |
3 files changed, 43 insertions, 6 deletions
diff --git a/src/libthread/exec.c b/src/libthread/exec.c index 2cbb4437..f31b004a 100644 --- a/src/libthread/exec.c +++ b/src/libthread/exec.c @@ -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]; @@ -97,6 +99,24 @@ threadspawn(int fd[3], char *cmd, char *argv[]) } 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[]) { int pid; diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c index 2ddd8c72..e1fed2bf 100644 --- a/src/libthread/pthread.c +++ b/src/libthread/pthread.c @@ -130,3 +130,9 @@ _pthreadinit(void) pthread_key_create(&prockey, 0); } +int +_runthreadspawn(int *fd, char *cmd, char **argv) +{ + return _threadspawn(fd, cmd, argv); +} + diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index d30d58b6..9f0a53d5 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -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**); |