Blob


1 #include "threadimpl.h"
3 int _threadnopasser;
5 #define NFN 33
6 #define ERRLEN 48
7 typedef struct Note Note;
8 struct Note
9 {
10 Lock inuse;
11 Proc *proc; /* recipient */
12 char s[ERRMAX]; /* arg2 */
13 };
15 static Note notes[128];
16 static Note *enotes = notes+nelem(notes);
17 static int (*onnote[NFN])(void*, char*);
18 static int onnotepid[NFN];
19 static Lock onnotelock;
21 int
22 threadnotify(int (*f)(void*, char*), int in)
23 {
24 int i, topid;
25 int (*from)(void*, char*), (*to)(void*, char*);
27 if(in){
28 from = 0;
29 to = f;
30 topid = _threadgetproc()->pid;
31 }else{
32 from = f;
33 to = 0;
34 topid = 0;
35 }
36 lock(&onnotelock);
37 for(i=0; i<NFN; i++)
38 if(onnote[i]==from){
39 onnote[i] = to;
40 onnotepid[i] = topid;
41 break;
42 }
43 unlock(&onnotelock);
44 return i<NFN;
45 }
47 static void
48 delayednotes(Proc *p, void *v)
49 {
50 int i;
51 Note *n;
52 int (*fn)(void*, char*);
54 if(!p->pending)
55 return;
57 p->pending = 0;
58 for(n=notes; n<enotes; n++){
59 if(n->proc == p){
60 for(i=0; i<NFN; i++){
61 if(onnotepid[i]!=p->pid || (fn = onnote[i])==0)
62 continue;
63 if((*fn)(v, n->s))
64 break;
65 }
66 if(i==NFN){
67 _threaddebug(DBGNOTE, "Unhandled note %s, proc %p\n", n->s, p);
68 if(strcmp(n->s, "sys: child") == 0)
69 noted(NCONT);
70 fprint(2, "unhandled note %s, pid %d\n", n->s, p->pid);
71 if(v != nil)
72 noted(NDFLT);
73 else if(strncmp(n->s, "sys:", 4)==0)
74 abort();
75 threadexitsall(n->s);
76 }
77 n->proc = nil;
78 unlock(&n->inuse);
79 }
80 }
81 }
83 void
84 _threadnote(void *v, char *s)
85 {
86 Proc *p;
87 Note *n;
89 _threaddebug(DBGNOTE, "Got note %s", s);
90 if(strncmp(s, "sys:", 4) == 0
91 && strcmp(s, "sys: write on closed pipe") != 0
92 && strcmp(s, "sys: child") != 0)
93 noted(NDFLT);
95 // if(_threadexitsallstatus){
96 // _threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'\n", _threadexitsallstatus);
97 // _exits(_threadexitsallstatus);
98 // }
100 if(strcmp(s, "threadint")==0 || strcmp(s, "interrupt")==0)
101 noted(NCONT);
103 p = _threadgetproc();
104 if(p == nil)
105 noted(NDFLT);
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);
120 int
121 _procsplhi(void)
123 int s;
124 Proc *p;
126 p = _threadgetproc();
127 s = p->splhi;
128 p->splhi = 1;
129 return s;
132 void
133 _procsplx(int s)
135 Proc *p;
137 p = _threadgetproc();
138 p->splhi = s;
139 if(s)
140 return;
141 /*
142 if(p->pending)
143 delayednotes(p, nil);
144 */