144 lines · 2.3 KB · C
RawDownload
/* 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	48typedef 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; intthreadnotify(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 voiddelayednotes(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);}