xref: /plan9/sys/src/cmd/execnet/note.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1 /* BUG BUG BUG */
2 
3 #include <u.h>
4 #include <libc.h>
5 #include <thread.h>
6 #include "/sys/src/libthread/threadimpl.h"
7 
8 int	_threadnopasser;
9 
10 #define	NFN		33
11 #define	ERRLEN	48
12 typedef struct Note Note;
13 struct Note
14 {
15 	Lock		inuse;
16 	Proc		*proc;		/* recipient */
17 	char		s[ERRMAX];	/* arg2 */
18 };
19 
20 static Note	notes[128];
21 static Note	*enotes = notes+nelem(notes);
22 static int		(*onnote[NFN])(void*, char*);
23 static int		onnotepid[NFN];
24 static Lock	onnotelock;
25 
26 int
threadnotify(int (* f)(void *,char *),int in)27 threadnotify(int (*f)(void*, char*), int in)
28 {
29 	int i, topid;
30 	int (*from)(void*, char*), (*to)(void*, char*);
31 
32 	if(in){
33 		from = nil;
34 		to = f;
35 		topid = _threadgetproc()->pid;
36 	}else{
37 		from = f;
38 		to = nil;
39 		topid = 0;
40 	}
41 	lock(&onnotelock);
42 	for(i=0; i<NFN; i++)
43 		if(onnote[i]==from){
44 			onnote[i] = to;
45 			onnotepid[i] = topid;
46 			break;
47 		}
48 	unlock(&onnotelock);
49 	return i<NFN;
50 }
51 
52 static void
delayednotes(Proc * p,void * v)53 delayednotes(Proc *p, void *v)
54 {
55 	int i;
56 	Note *n;
57 	int (*fn)(void*, char*);
58 
59 	if(!p->pending)
60 		return;
61 
62 	p->pending = 0;
63 	for(n=notes; n<enotes; n++){
64 		if(n->proc == p){
65 			for(i=0; i<NFN; i++){
66 				if(onnotepid[i]!=p->pid || (fn = onnote[i])==nil)
67 					continue;
68 				if((*fn)(v, n->s))
69 					break;
70 			}
71 			if(i==NFN){
72 				_threaddebug(DBGNOTE, "Unhandled note %s, proc %p\n", n->s, p);
73 				if(v != nil)
74 					noted(NDFLT);
75 				else if(strncmp(n->s, "sys:", 4)==0)
76 					abort();
77 				threadexitsall(n->s);
78 			}
79 			n->proc = nil;
80 			unlock(&n->inuse);
81 		}
82 	}
83 }
84 
85 void
_threadnote(void * v,char * s)86 _threadnote(void *v, char *s)
87 {
88 	Proc *p;
89 	Note *n;
90 
91 	_threaddebug(DBGNOTE, "Got note %s", s);
92 //	if(strncmp(s, "sys:", 4) == 0)
93 //		noted(NDFLT);
94 
95 //	if(_threadexitsallstatus){
96 //		_threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'\n", _threadexitsallstatus);
97 //		_exits(_threadexitsallstatus);
98 //	}
99 
100 	if(strcmp(s, "threadint")==0)
101 		noted(NCONT);
102 
103 	p = _threadgetproc();
104 	if(p == nil)
105 		noted(NDFLT);
106 
107 	for(n=notes; n<enotes; n++)
108 		if(canlock(&n->inuse))
109 			break;
110 	if(n==enotes)
111 		sysfatal("libthread: too many delayed notes");
112 	utfecpy(n->s, n->s+ERRMAX, s);
113 	n->proc = p;
114 	p->pending = 1;
115 	if(!p->splhi)
116 		delayednotes(p, v);
117 	noted(NCONT);
118 }
119 
120 int
_procsplhi(void)121 _procsplhi(void)
122 {
123 	int s;
124 	Proc *p;
125 
126 	p = _threadgetproc();
127 	s = p->splhi;
128 	p->splhi = 1;
129 	return s;
130 }
131 
132 void
_procsplx(int s)133 _procsplx(int s)
134 {
135 	Proc *p;
136 
137 	p = _threadgetproc();
138 	p->splhi = s;
139 	if(s)
140 		return;
141 	if(p->pending)
142 		delayednotes(p, nil);
143 }
144 
145