From 175b8a534ae5729ac10ea793410a40bfa4a30608 Mon Sep 17 00:00:00 2001 From: rsc Date: Wed, 21 Apr 2004 04:48:25 +0000 Subject: No more malloc or lock inside signal handlers. --- src/lib9/_p9proc.c | 110 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 44 deletions(-) (limited to 'src/lib9/_p9proc.c') diff --git a/src/lib9/_p9proc.c b/src/lib9/_p9proc.c index 6e4010cd..374fb089 100644 --- a/src/lib9/_p9proc.c +++ b/src/lib9/_p9proc.c @@ -1,73 +1,95 @@ +/* + * This needs to be callable from a signal handler, so it has been + * written to avoid locks. The only lock is the one used to acquire + * an entry in the table, and we make sure that acquiring is done + * when not in a handler. Lookup and delete do not need locks. + * It's a scan-forward hash table. To avoid breaking chains, + * T ((void*)-1) is used as a non-breaking nil. + */ + #include #include #include "9proc.h" +enum { PIDHASH = 1021 }; + +#define T ((void*)-1) +static Uproc *alluproc[PIDHASH]; +static int allupid[PIDHASH]; static Lock uproclock; -static Uproc *phash[PIDHASH]; Uproc* -_p9uproc(void) +_p9uproc(int inhandler) { - /* for now, assume getpid is fast or cached */ - int pid; + int i, h, pid; Uproc *up; + /* for now, assume getpid is fast or cached */ pid = getpid(); -again: -if(0)print("find %d\n", pid); - lock(&uproclock); - for(up=phash[pid%PIDHASH]; up; up=up->next){ - if(up->pid == pid){ -if(0)print("found %d\n", pid); - unlock(&uproclock); + + /* + * this part - the lookup - needs to run without locks + * so that it can safely be called from within the notify handler. + * notify calls _p9uproc, and fork and rfork call _p9uproc + * in both parent and child, so if we're in a signal handler, + * we should find something in the table. + */ + h = pid%PIDHASH; + for(i=0; ipipe) < 0){ -if(0)print("againpipe %d\n", pid); + /* need to allocate */ + while((up = mallocz(sizeof(Uproc), 1)) == nil) sleep(1000); - goto againpipe; - } - up->pid = pid; - up->next = phash[pid%PIDHASH]; - phash[pid%PIDHASH] = up; -if(0)print("link %d\n", pid); + up = mallocz(sizeof(Uproc), 1); + lock(&uproclock); + h = pid%PIDHASH; + for(i=0; inext){ - if((*l)->pid == pid){ - up = *l; - *l = up->next; -if(0)print("died %d\n", pid); - unlock(&uproclock); - close(up->pipe[0]); - close(up->pipe[1]); + h = pid%PIDHASH; + for(i=0; i