diff options
Diffstat (limited to 'src/libthread/execproc.ch')
-rw-r--r-- | src/libthread/execproc.ch | 183 |
1 files changed, 0 insertions, 183 deletions
diff --git a/src/libthread/execproc.ch b/src/libthread/execproc.ch deleted file mode 100644 index 4382be40..00000000 --- a/src/libthread/execproc.ch +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Set up a dedicated proc to handle calls to exec. - * The proc also waits for child messages. - * This way, each proc scheduler need not worry - * about calling wait in its main loop. - * - * To be included from other files (e.g., Linux-clone.c). - */ - -typedef struct Xarg Xarg; -struct Xarg -{ - Channel *pidc; - int fd[3]; - char *prog; - char **args; - int freeargs; - Channel *ret; - int errn; - char errstr[ERRMAX]; -}; - -static Proc *_threadexecproc; -static Channel *_threadexecchan; -static Lock threadexeclock; - -/* - * Called to poll for any kids of this pthread. - * We have a separate proc responsible for exec, - * so this is a no-op. - */ -void -_threadwaitkids(Proc *p) -{ -} - -#define WAITSIG SIGCHLD - -/* - * Separate process to wait for child messages. - * Also runs signal handlers and runs all execs. - */ -static void -nop(int sig) -{ - USED(sig); -} - -static void -_threadwaitproc(void *v) -{ - Channel *c; - Waitmsg *w; - sigset_t mask; - int ret, nkids; - Xarg *xa; - - nkids = 0; - - sigemptyset(&mask); - siginterrupt(WAITSIG, 1); - signal(WAITSIG, nop); - sigaddset(&mask, WAITSIG); - sigprocmask(SIG_BLOCK, &mask, nil); - USED(v); - for(;;){ - while((nkids > 0 ? nbrecv : recv)(_threadexecchan, &xa) == 1){ - ret = _threadexec(xa->pidc, xa->fd, xa->prog, xa->args, xa->freeargs); - if(ret > 0) - nkids++; - else{ - rerrstr(xa->errstr, sizeof xa->errstr); - xa->errn = errno; - } - sendul(xa->ret, ret); - } - if(nkids > 0){ - sigprocmask(SIG_UNBLOCK, &mask, nil); - w = wait(); - sigprocmask(SIG_BLOCK, &mask, nil); - if(w == nil && errno == ECHILD){ - fprint(2, "wait returned ECHILD but nkids=%d; reset\n", nkids); - nkids = 0; - } - if(w){ - nkids--; - if((c = _threadwaitchan) != nil) - sendp(c, w); - else - free(w); - } - } - } -} - -static void _kickexecproc(void); - -int -_callthreadexec(Channel *pidc, int fd[3], char *prog, char *args[], int freeargs) -{ - int ret; - Xarg xa; - - if(_threadexecchan == nil){ - lock(&threadexeclock); - if(_threadexecchan == nil) - _threadfirstexec(); - unlock(&threadexeclock); - } - - xa.pidc = pidc; - xa.fd[0] = fd[0]; - xa.fd[1] = fd[1]; - xa.fd[2] = fd[2]; - xa.prog = prog; - xa.args = args; - xa.freeargs = freeargs; - xa.ret = chancreate(sizeof(ulong), 1); - sendp(_threadexecchan, &xa); - _kickexecproc(); - ret = recvul(xa.ret); - if(ret < 0){ - werrstr("%s", xa.errstr); - errno = xa.errn; - } - chanfree(xa.ret); - return ret; -} - -/* - * Called before the first exec. - */ -void -_threadfirstexec(void) -{ - int id; - Proc *p; - - _threadexecchan = chancreate(sizeof(Xarg*), 1); - id = proccreate(_threadwaitproc, nil, 32*1024); - - /* - * Sleazy: decrement threadnprocs so that - * the existence of the _threadwaitproc proc - * doesn't keep us from exiting. - */ - lock(&_threadpq.lock); - --_threadnprocs; - for(p=_threadpq.head; p; p=p->next) - if(p->threads.head && p->threads.head->id == id) - break; - if(p == nil) - sysfatal("cannot find exec proc"); - unlock(&_threadpq.lock); - _threadexecproc = p; -} - -/* - * Called after the thread t has been rescheduled. - * Kick the exec proc in case it is in the middle of a wait. - */ -static void -_kickexecproc(void) -{ - kill(_threadexecproc->pid, WAITSIG); -} - -/* - * Called before exec. - */ -void -_threadbeforeexec(void) -{ -} - -/* - * Called after exec. - */ -void -_threadafterexec(void) -{ -} - |