try to implement the daemonize hack.
This commit is contained in:
parent
048610b7ea
commit
5093c3fa40
11 changed files with 165 additions and 51 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
|
#if defined(__linux__)
|
||||||
#include "ucontext.c"
|
#include "ucontext.c"
|
||||||
|
#else
|
||||||
#ifdef OLD
|
|
||||||
|
|
||||||
#include "threadimpl.h"
|
#include "threadimpl.h"
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,9 @@ _newthread(Proc *p, void (*f)(void *arg), void *arg, uint stacksize,
|
||||||
|
|
||||||
t = _threadmalloc(sizeof(Thread), 1);
|
t = _threadmalloc(sizeof(Thread), 1);
|
||||||
t->proc = p;
|
t->proc = p;
|
||||||
|
t->nextproc = p;
|
||||||
|
t->homeproc = p;
|
||||||
|
|
||||||
t->grp = grp;
|
t->grp = grp;
|
||||||
t->id = id = newthreadid();
|
t->id = id = newthreadid();
|
||||||
if(name)
|
if(name)
|
||||||
|
|
@ -42,15 +45,7 @@ _newthread(Proc *p, void (*f)(void *arg), void *arg, uint stacksize,
|
||||||
* Add thread to proc.
|
* Add thread to proc.
|
||||||
*/
|
*/
|
||||||
lock(&p->lock);
|
lock(&p->lock);
|
||||||
p->nthreads++;
|
_procaddthread(p, t);
|
||||||
if(p->threads.head == nil)
|
|
||||||
p->threads.head = t;
|
|
||||||
else{
|
|
||||||
t->prevt = p->threads.tail;
|
|
||||||
t->prevt->nextt = t;
|
|
||||||
}
|
|
||||||
p->threads.tail = t;
|
|
||||||
t->next = (Thread*)~0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mark thread as ready to run.
|
* Mark thread as ready to run.
|
||||||
|
|
@ -123,7 +118,7 @@ threadcreateidle(void (*f)(void *arg), void *arg, uint stacksize)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
assert(_threadnprocs == 1);
|
assert(_threadpq.head->next == nil); /* only 1 */
|
||||||
|
|
||||||
id = threadcreate(f, arg, stacksize);
|
id = threadcreate(f, arg, stacksize);
|
||||||
_threaddebug(DBGSCHED, "idle is %d", id);
|
_threaddebug(DBGSCHED, "idle is %d", id);
|
||||||
|
|
@ -181,3 +176,36 @@ newprocid(void)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add thread to proc's list.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_procaddthread(Proc *p, Thread *t)
|
||||||
|
{
|
||||||
|
p->nthreads++;
|
||||||
|
if(p->threads.head == nil)
|
||||||
|
p->threads.head = t;
|
||||||
|
else{
|
||||||
|
t->prevt = p->threads.tail;
|
||||||
|
t->prevt->nextt = t;
|
||||||
|
}
|
||||||
|
p->threads.tail = t;
|
||||||
|
t->next = (Thread*)~0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove thread from proc's list.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_procdelthread(Proc *p, Thread *t)
|
||||||
|
{
|
||||||
|
if(t->prevt)
|
||||||
|
t->prevt->nextt = t->nextt;
|
||||||
|
else
|
||||||
|
p->threads.head = t->nextt;
|
||||||
|
if(t->nextt)
|
||||||
|
t->nextt->prevt = t->prevt;
|
||||||
|
else
|
||||||
|
p->threads.tail = t->prevt;
|
||||||
|
p->nthreads--;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include "threadimpl.h"
|
#include "threadimpl.h"
|
||||||
|
|
||||||
static void efork(int[3], int[2], char*, char**);
|
static void efork(int[3], int[2], char*, char**);
|
||||||
static int
|
int
|
||||||
_threadexec(Channel *pidc, int fd[3], char *prog, char *args[], int freeargs)
|
_threadexec(Channel *pidc, int fd[3], char *prog, char *args[], int freeargs)
|
||||||
{
|
{
|
||||||
int pfd[2];
|
int pfd[2];
|
||||||
|
|
@ -88,14 +88,14 @@ Bad:
|
||||||
void
|
void
|
||||||
threadexec(Channel *pidc, int fd[3], char *prog, char *args[])
|
threadexec(Channel *pidc, int fd[3], char *prog, char *args[])
|
||||||
{
|
{
|
||||||
if(_threadexec(pidc, fd, prog, args, 0) >= 0)
|
if(_callthreadexec(pidc, fd, prog, args, 0) >= 0)
|
||||||
threadexits(nil);
|
threadexits(nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
threadspawn(int fd[3], char *prog, char *args[])
|
threadspawn(int fd[3], char *prog, char *args[])
|
||||||
{
|
{
|
||||||
return _threadexec(nil, fd, prog, args, 0);
|
return _callthreadexec(nil, fd, prog, args, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -128,7 +128,7 @@ threadexecl(Channel *pidc, int fd[3], char *f, ...)
|
||||||
args[n] = 0;
|
args[n] = 0;
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
|
|
||||||
if(_threadexec(pidc, fd, f, args, 1) >= 0)
|
if(_callthreadexec(pidc, fd, f, args, 1) >= 0)
|
||||||
threadexits(nil);
|
threadexits(nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ threadfdwaitsetup(void)
|
||||||
|
|
||||||
if(!setup){
|
if(!setup){
|
||||||
setup = 1;
|
setup = 1;
|
||||||
threadcreateidle(pollidle, nil, 16384);
|
proccreate(pollidle, nil, 16384);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,11 @@ struct Mainarg
|
||||||
char **argv;
|
char **argv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int _threadmainpid;
|
||||||
int mainstacksize;
|
int mainstacksize;
|
||||||
|
int _callsthreaddaemonize;
|
||||||
|
static int passtomainpid;
|
||||||
|
|
||||||
extern void (*_sysfatal)(char*, va_list);
|
extern void (*_sysfatal)(char*, va_list);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -25,15 +29,53 @@ mainlauncher(void *arg)
|
||||||
threadexits("threadmain");
|
threadexits("threadmain");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
passer(void *x, char *msg)
|
||||||
|
{
|
||||||
|
USED(x);
|
||||||
|
Waitmsg *w;
|
||||||
|
|
||||||
|
if(strcmp(msg, "sys: usr2") == 0)
|
||||||
|
_exit(0); /* daemonize */
|
||||||
|
else if(strcmp(msg, "sys: child") == 0){
|
||||||
|
w = wait();
|
||||||
|
if(w == nil)
|
||||||
|
_exit(1);
|
||||||
|
_exit(atoi(w->msg));
|
||||||
|
}else
|
||||||
|
postnote(PNPROC, passtomainpid, msg);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
int pid;
|
||||||
Mainarg a;
|
Mainarg a;
|
||||||
Proc *p;
|
Proc *p;
|
||||||
|
sigset_t mask;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX Do daemonize hack here.
|
* Do daemonize hack here.
|
||||||
*/
|
*/
|
||||||
|
if(_callsthreaddaemonize){
|
||||||
|
passtomainpid = getpid();
|
||||||
|
switch(pid = fork()){
|
||||||
|
case -1:
|
||||||
|
sysfatal("fork: %r");
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
/* continue executing */
|
||||||
|
_threadmainpid = getppid();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* wait for signal USR2 */
|
||||||
|
notify(passer);
|
||||||
|
for(;;)
|
||||||
|
pause();
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Instruct QLock et al. to use our scheduling functions
|
* Instruct QLock et al. to use our scheduling functions
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
<$PLAN9/src/mkhdr
|
<$PLAN9/src/mkhdr
|
||||||
|
|
||||||
LIB=libthread.a
|
LIB=libthread.a
|
||||||
|
THREAD=`sh ./thread.sh`
|
||||||
OFILES=\
|
OFILES=\
|
||||||
$OBJTYPE.$O\
|
$OBJTYPE.$O\
|
||||||
|
$THREAD.$O\
|
||||||
asm-$SYSNAME-$OBJTYPE.$O\
|
asm-$SYSNAME-$OBJTYPE.$O\
|
||||||
channel.$O\
|
channel.$O\
|
||||||
chanprint.$O\
|
chanprint.$O\
|
||||||
create.$O\
|
create.$O\
|
||||||
|
daemon.$O\
|
||||||
debug.$O\
|
debug.$O\
|
||||||
exec-unix.$O\
|
exec-unix.$O\
|
||||||
exit.$O\
|
exit.$O\
|
||||||
|
|
@ -28,7 +30,6 @@ OFILES=\
|
||||||
memset.$O\
|
memset.$O\
|
||||||
memsetd.$O\
|
memsetd.$O\
|
||||||
note.$O\
|
note.$O\
|
||||||
pthread.$O\
|
|
||||||
read9pmsg.$O\
|
read9pmsg.$O\
|
||||||
ref.$O\
|
ref.$O\
|
||||||
sched.$O\
|
sched.$O\
|
||||||
|
|
@ -69,3 +70,4 @@ VG=`test -d /home/rsc/pub/valgrind-debian && echo -DUSEVALGRIND`
|
||||||
|
|
||||||
CFLAGS=$CFLAGS $VG
|
CFLAGS=$CFLAGS $VG
|
||||||
|
|
||||||
|
Linux-clone.$O: execproc.ch exit-getpid.ch proctab.ch procstack.ch
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "threadimpl.h"
|
#include "threadimpl.h"
|
||||||
|
|
||||||
|
|
||||||
int _threadnopasser;
|
int _threadnopasser;
|
||||||
|
|
||||||
#define NFN 33
|
#define NFN 33
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,25 @@ _threadgetproc(void)
|
||||||
return pthread_getspecific(key);
|
return pthread_getspecific(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called to start a new proc.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_threadstartproc(Proc *p)
|
||||||
|
{
|
||||||
|
Proc *np;
|
||||||
|
pthread_t tid;
|
||||||
|
sigset_t all;
|
||||||
|
|
||||||
|
np = p->newproc;
|
||||||
|
sigfillset(&all);
|
||||||
|
pthread_sigmask(SIG_SETMASK, &all, nil);
|
||||||
|
if(pthread_create(&tid, nil, (void*(*)(void*))_threadscheduler,
|
||||||
|
np) < 0)
|
||||||
|
sysfatal("pthread_create: %r");
|
||||||
|
np->pthreadid = tid;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called to associate p with the current pthread.
|
* Called to associate p with the current pthread.
|
||||||
*/
|
*/
|
||||||
|
|
@ -87,9 +106,10 @@ _threadwaitkids(Proc *p)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Separate process to wait for child messages.
|
* Separate process to wait for child messages.
|
||||||
|
* Also runs signal handlers.
|
||||||
*/
|
*/
|
||||||
Channel *_threadexecchan;
|
static Channel *_threadexecchan;
|
||||||
void
|
static void
|
||||||
_threadwaitproc(void *v)
|
_threadwaitproc(void *v)
|
||||||
{
|
{
|
||||||
Channel *c;
|
Channel *c;
|
||||||
|
|
@ -124,6 +144,9 @@ _threadfirstexec(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called from mainlauncher before threadmain.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
_threadmaininit(void)
|
_threadmaininit(void)
|
||||||
{
|
{
|
||||||
|
|
@ -141,27 +164,12 @@ _threadmaininit(void)
|
||||||
unlock(&_threadpq.lock);
|
unlock(&_threadpq.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called after forking the exec child.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
_threadafterexec(void)
|
_threadafterexec(void)
|
||||||
{
|
{
|
||||||
nbsendul(_threadexecchan, 1);
|
nbsendul(_threadexecchan, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Called to start a new proc.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
_threadstartproc(Proc *p)
|
|
||||||
{
|
|
||||||
Proc *np;
|
|
||||||
pthread_t tid;
|
|
||||||
sigset_t all;
|
|
||||||
|
|
||||||
np = p->newproc;
|
|
||||||
sigfillset(&all);
|
|
||||||
pthread_sigmask(SIG_SETMASK, &all, nil);
|
|
||||||
if(pthread_create(&tid, nil, (void*(*)(void*))_threadscheduler,
|
|
||||||
np) < 0)
|
|
||||||
sysfatal("pthread_create: %r");
|
|
||||||
np->pthreadid = tid;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -51,27 +51,42 @@ _threadscheduler(void *arg)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If thread needs to die, kill it.
|
* If thread needs to die, kill it.
|
||||||
|
* t->proc == p may not be true if we're
|
||||||
|
* trying to jump into the exec proc (see exec-unix.c).
|
||||||
*/
|
*/
|
||||||
if(t->moribund){
|
if(t->moribund){
|
||||||
_threaddebug(DBGSCHED, "moribund %d.%d", p->id, t->id);
|
_threaddebug(DBGSCHED, "moribund %d.%d", p->id, t->id);
|
||||||
|
if(t->moribund != 1)
|
||||||
|
print("moribund broke %p %d\n", &t->moribund, t->moribund);
|
||||||
assert(t->moribund == 1);
|
assert(t->moribund == 1);
|
||||||
t->state = Dead;
|
t->state = Dead;
|
||||||
if(t->prevt)
|
_procdelthread(p, t);
|
||||||
t->prevt->nextt = t->nextt;
|
|
||||||
else
|
|
||||||
p->threads.head = t->nextt;
|
|
||||||
if(t->nextt)
|
|
||||||
t->nextt->prevt = t->prevt;
|
|
||||||
else
|
|
||||||
p->threads.tail = t->prevt;
|
|
||||||
unlock(&p->lock);
|
unlock(&p->lock);
|
||||||
_threadfree(t);
|
_threadfree(t);
|
||||||
p->nthreads--;
|
|
||||||
t = nil;
|
t = nil;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the thread has asked to move to another proc,
|
||||||
|
* let it go (only to be used in *very* special situations).
|
||||||
|
if(t->nextproc != p)
|
||||||
|
_procdelthread(p, t);
|
||||||
|
*/
|
||||||
|
|
||||||
unlock(&p->lock);
|
unlock(&p->lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the thread has asked to move to another proc,
|
||||||
|
* add it to the new proc.
|
||||||
|
*/
|
||||||
|
if(t->nextproc != p){
|
||||||
|
// lock(&t->nextproc->lock);
|
||||||
|
// _procaddthread(t->nextproc, t);
|
||||||
|
// unlock(&t->nextproc->lock);
|
||||||
|
t->proc = t->nextproc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is a request to run a function on the
|
* If there is a request to run a function on the
|
||||||
* scheduling stack, do so.
|
* scheduling stack, do so.
|
||||||
|
|
@ -87,7 +102,7 @@ _threadscheduler(void *arg)
|
||||||
* Move the thread along.
|
* Move the thread along.
|
||||||
*/
|
*/
|
||||||
t->state = t->nextstate;
|
t->state = t->nextstate;
|
||||||
_threaddebug(DBGSCHED, "moveon %d.%d", p->id, t->id);
|
_threaddebug(DBGSCHED, "moveon %d.%d", t->proc->id, t->id);
|
||||||
if(t->state == Ready)
|
if(t->state == Ready)
|
||||||
_threadready(t);
|
_threadready(t);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,15 +22,20 @@ threadmain(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Channel *c;
|
Channel *c;
|
||||||
Waitmsg *w;
|
Waitmsg *w;
|
||||||
|
int (*mk)(void(*)(void*), void*, uint);
|
||||||
|
|
||||||
|
mk = threadcreate;
|
||||||
ARGBEGIN{
|
ARGBEGIN{
|
||||||
case 'D':
|
case 'D':
|
||||||
_threaddebuglevel = ~0;
|
_threaddebuglevel = ~0;
|
||||||
break;
|
break;
|
||||||
|
case 'p':
|
||||||
|
mk = proccreate;
|
||||||
|
break;
|
||||||
}ARGEND
|
}ARGEND
|
||||||
|
|
||||||
c = threadwaitchan();
|
c = threadwaitchan();
|
||||||
proccreate(doexec, argv, 8192);
|
mk(doexec, argv, 8192);
|
||||||
w = recvp(c);
|
w = recvp(c);
|
||||||
if(w == nil)
|
if(w == nil)
|
||||||
print("exec/recvp failed: %r\n");
|
print("exec/recvp failed: %r\n");
|
||||||
|
|
|
||||||
|
|
@ -70,11 +70,13 @@ struct Thread
|
||||||
int asleep; /* thread is in _threadsleep */
|
int asleep; /* thread is in _threadsleep */
|
||||||
Label context; /* for context switches */
|
Label context; /* for context switches */
|
||||||
int grp; /* thread group */
|
int grp; /* thread group */
|
||||||
|
Proc *homeproc; /* ``home'' proc */
|
||||||
int id; /* thread id */
|
int id; /* thread id */
|
||||||
int moribund; /* thread needs to die */
|
int moribund; /* thread needs to die */
|
||||||
char *name; /* name of thread */
|
char *name; /* name of thread */
|
||||||
Thread *next; /* next on ready queue */
|
Thread *next; /* next on ready queue */
|
||||||
Thread *nextt; /* next on list of threads in this proc */
|
Thread *nextt; /* next on list of threads in this proc */
|
||||||
|
Proc *nextproc; /* next proc in which to run (rarely changes) */
|
||||||
State nextstate; /* next run state */
|
State nextstate; /* next run state */
|
||||||
Proc *proc; /* proc of this thread */
|
Proc *proc; /* proc of this thread */
|
||||||
Thread *prevt; /* prev on list of threads in this proc */
|
Thread *prevt; /* prev on list of threads in this proc */
|
||||||
|
|
@ -117,6 +119,7 @@ struct Proc
|
||||||
Thread *thread; /* running thread */
|
Thread *thread; /* running thread */
|
||||||
Thread *idle; /* idle thread */
|
Thread *idle; /* idle thread */
|
||||||
int id;
|
int id;
|
||||||
|
int procid;
|
||||||
|
|
||||||
int needexec;
|
int needexec;
|
||||||
Execargs exec; /* exec argument */
|
Execargs exec; /* exec argument */
|
||||||
|
|
@ -195,7 +198,9 @@ void threadstatus(void);
|
||||||
void _threadstartproc(Proc*);
|
void _threadstartproc(Proc*);
|
||||||
void _threadexitproc(char*);
|
void _threadexitproc(char*);
|
||||||
void _threadexitallproc(char*);
|
void _threadexitallproc(char*);
|
||||||
|
void _threadefork(int[3], int[2], char*, char**);
|
||||||
|
|
||||||
|
extern int _threadmainpid;
|
||||||
extern int _threadnprocs;
|
extern int _threadnprocs;
|
||||||
extern int _threaddebuglevel;
|
extern int _threaddebuglevel;
|
||||||
extern char* _threadexitsallstatus;
|
extern char* _threadexitsallstatus;
|
||||||
|
|
@ -214,3 +219,11 @@ extern void _threadmemset(void*, int, int);
|
||||||
extern void _threaddebugmemset(void*, int, int);
|
extern void _threaddebugmemset(void*, int, int);
|
||||||
extern int _threadprocs;
|
extern int _threadprocs;
|
||||||
extern void _threadstacklimit(void*, void*);
|
extern void _threadstacklimit(void*, void*);
|
||||||
|
extern void _procdelthread(Proc*, Thread*);
|
||||||
|
extern void _procaddthread(Proc*, Thread*);
|
||||||
|
|
||||||
|
extern void _threadafterexec(void);
|
||||||
|
extern void _threadmaininit(void);
|
||||||
|
extern void _threadfirstexec(void);
|
||||||
|
extern int _threadexec(Channel*, int[3], char*, char*[], int);
|
||||||
|
extern int _callthreadexec(Channel*, int[3], char*, char*[], int);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue