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