diff options
Diffstat (limited to 'src/libthread/note.c')
-rw-r--r-- | src/libthread/note.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/libthread/note.c b/src/libthread/note.c new file mode 100644 index 00000000..b7f4b137 --- /dev/null +++ b/src/libthread/note.c @@ -0,0 +1,143 @@ +#include "threadimpl.h" + +int _threadnopasser; + +#ifdef NOTDEF +#define NFN 33 +#define ERRLEN 48 +typedef struct Note Note; +struct Note +{ + Lock inuse; + Proc *proc; /* recipient */ + char s[ERRMAX]; /* arg2 */ +}; + +static Note notes[128]; +static Note *enotes = notes+nelem(notes); +static int (*onnote[NFN])(void*, char*); +static int onnotepid[NFN]; +static Lock onnotelock; + +int +threadnotify(int (*f)(void*, char*), int in) +{ + int i, topid; + int (*from)(void*, char*), (*to)(void*, char*); + + if(in){ + from = nil; + to = f; + topid = _threadgetproc()->pid; + }else{ + from = f; + to = nil; + topid = 0; + } + lock(&onnotelock); + for(i=0; i<NFN; i++) + if(onnote[i]==from){ + onnote[i] = to; + onnotepid[i] = topid; + break; + } + unlock(&onnotelock); + return i<NFN; +} + +static void +delayednotes(Proc *p, void *v) +{ + int i; + Note *n; + int (*fn)(void*, char*); + + if(!p->pending) + return; + + p->pending = 0; + for(n=notes; n<enotes; n++){ + if(n->proc == p){ + for(i=0; i<NFN; i++){ + if(onnotepid[i]!=p->pid || (fn = onnote[i])==nil) + continue; + if((*fn)(v, n->s)) + break; + } + if(i==NFN){ + _threaddebug(DBGNOTE, "Unhandled note %s, proc %p\n", n->s, p); + if(v != nil) + noted(NDFLT); + else if(strncmp(n->s, "sys:", 4)==0) + abort(); + threadexitsall(n->s); + } + n->proc = nil; + unlock(&n->inuse); + } + } +} + +void +_threadnote(void *v, char *s) +{ + Proc *p; + Note *n; + + _threaddebug(DBGNOTE, "Got note %s", s); + if(strncmp(s, "sys:", 4) == 0) + noted(NDFLT); + +// if(_threadexitsallstatus){ +// _threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'\n", _threadexitsallstatus); +// _exits(_threadexitsallstatus); +// } + + if(strcmp(s, "threadint")==0) + noted(NCONT); + + p = _threadgetproc(); + if(p == nil) + noted(NDFLT); + + for(n=notes; n<enotes; n++) + if(canlock(&n->inuse)) + break; + if(n==enotes) + sysfatal("libthread: too many delayed notes"); + utfecpy(n->s, n->s+ERRMAX, s); + n->proc = p; + p->pending = 1; + if(!p->splhi) + delayednotes(p, v); + noted(NCONT); +} +#endif + +int +_procsplhi(void) +{ + int s; + Proc *p; + + p = _threadgetproc(); + s = p->splhi; + p->splhi = 1; + return s; +} + +void +_procsplx(int s) +{ + Proc *p; + + p = _threadgetproc(); + p->splhi = s; + if(s) + return; +/* + if(p->pending) + delayednotes(p, nil); +*/ +} + |