123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- /* BUG BUG BUG */
- #include <u.h>
- #include <libc.h>
- #include <thread.h>
- #include "/sys/src/libthread/threadimpl.h"
- int _threadnopasser;
- #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);
- }
- 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);
- }
|