tshuffle to allow use of execchan in non-pthreads impls - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit e127e40bb1327662a05f5b70dd1bbca5c69b042c
 (DIR) parent e8a7b9699925f3f650593d07eb382155e9374ae6
 (HTM) Author: rsc <devnull@localhost>
       Date:   Mon, 27 Dec 2004 17:19:44 +0000
       
       shuffle to allow use of execchan in non-pthreads impls
       
       Diffstat:
         M src/libthread/exec.c                |      32 +++++++++++++++++++++++++------
         M src/libthread/pthread.c             |       6 ++++++
         M src/libthread/threadimpl.h          |      11 +++++++++++
       
       3 files changed, 43 insertions(+), 6 deletions(-)
       ---
 (DIR) diff --git a/src/libthread/exec.c b/src/libthread/exec.c
       t@@ -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);
                        }
       t@@ -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];
       t@@ -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;
 (DIR) diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c
       t@@ -130,3 +130,9 @@ _pthreadinit(void)
                pthread_key_create(&prockey, 0);
        }
        
       +int
       +_runthreadspawn(int *fd, char *cmd, char **argv)
       +{
       +        return _threadspawn(fd, cmd, argv);
       +}
       +
 (DIR) diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
       t@@ -1,6 +1,7 @@
        #include <ucontext.h>
        
        typedef struct Context Context;
       +typedef struct Execjob Execjob;
        typedef struct Proc Proc;
        typedef struct _Procrendez _Procrendez;
        
       t@@ -20,6 +21,14 @@ struct Context
                ucontext_t        uc;
        };
        
       +struct Execjob
       +{
       +        int *fd;
       +        char *cmd;
       +        char **argv;
       +        Channel *c;
       +};
       +
        struct _Thread
        {
                _Thread        *next;
       t@@ -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**);