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