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 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 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 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 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 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