Import sources from 2011-03-30 iso image
This commit is contained in:
commit
e5888a1ffd
7810 changed files with 2489717 additions and 0 deletions
142
sys/src/libthread/note.c
Executable file
142
sys/src/libthread/note.c
Executable file
|
@ -0,0 +1,142 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <thread.h>
|
||||
#include "threadimpl.h"
|
||||
|
||||
int _threadnopasser;
|
||||
|
||||
#define NFN 33
|
||||
#define ERRLEN 48
|
||||
typedef struct Note Note;
|
||||
struct Note
|
||||
{
|
||||
Lock inuse;
|
||||
Proc *proc; /* recipient */
|
||||
char s[ERRMAX]; /* arg2 */
|
||||
};
|
||||
|
||||
static Note notes[128];
|
||||
static Note *enotes = notes+nelem(notes);
|
||||
static int (*onnote[NFN])(void*, char*);
|
||||
static int onnotepid[NFN];
|
||||
static Lock onnotelock;
|
||||
|
||||
int
|
||||
threadnotify(int (*f)(void*, char*), int in)
|
||||
{
|
||||
int i, topid;
|
||||
int (*from)(void*, char*), (*to)(void*, char*);
|
||||
|
||||
if(in){
|
||||
from = nil;
|
||||
to = f;
|
||||
topid = _threadgetproc()->pid;
|
||||
}else{
|
||||
from = f;
|
||||
to = nil;
|
||||
topid = 0;
|
||||
}
|
||||
lock(&onnotelock);
|
||||
for(i=0; i<NFN; i++)
|
||||
if(onnote[i]==from){
|
||||
onnote[i] = to;
|
||||
onnotepid[i] = topid;
|
||||
break;
|
||||
}
|
||||
unlock(&onnotelock);
|
||||
return i<NFN;
|
||||
}
|
||||
|
||||
static void
|
||||
delayednotes(Proc *p, void *v)
|
||||
{
|
||||
int i;
|
||||
Note *n;
|
||||
int (*fn)(void*, char*);
|
||||
|
||||
if(!p->pending)
|
||||
return;
|
||||
|
||||
p->pending = 0;
|
||||
for(n=notes; n<enotes; n++){
|
||||
if(n->proc == p){
|
||||
for(i=0; i<NFN; i++){
|
||||
if(onnotepid[i]!=p->pid || (fn = onnote[i])==nil)
|
||||
continue;
|
||||
if((*fn)(v, n->s))
|
||||
break;
|
||||
}
|
||||
if(i==NFN){
|
||||
_threaddebug(DBGNOTE, "Unhandled note %s, proc %p\n", n->s, p);
|
||||
if(v != nil)
|
||||
noted(NDFLT);
|
||||
else if(strncmp(n->s, "sys:", 4)==0)
|
||||
abort();
|
||||
threadexitsall(n->s);
|
||||
}
|
||||
n->proc = nil;
|
||||
unlock(&n->inuse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_threadnote(void *v, char *s)
|
||||
{
|
||||
Proc *p;
|
||||
Note *n;
|
||||
|
||||
_threaddebug(DBGNOTE, "Got note %s", s);
|
||||
if(strncmp(s, "sys:", 4) == 0)
|
||||
noted(NDFLT);
|
||||
|
||||
if(_threadexitsallstatus){
|
||||
_threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'\n", _threadexitsallstatus);
|
||||
_exits(_threadexitsallstatus);
|
||||
}
|
||||
|
||||
if(strcmp(s, "threadint")==0)
|
||||
noted(NCONT);
|
||||
|
||||
p = _threadgetproc();
|
||||
if(p == nil)
|
||||
noted(NDFLT);
|
||||
|
||||
for(n=notes; n<enotes; n++)
|
||||
if(canlock(&n->inuse))
|
||||
break;
|
||||
if(n==enotes)
|
||||
sysfatal("libthread: too many delayed notes");
|
||||
utfecpy(n->s, n->s+ERRMAX, s);
|
||||
n->proc = p;
|
||||
p->pending = 1;
|
||||
if(!p->splhi)
|
||||
delayednotes(p, v);
|
||||
noted(NCONT);
|
||||
}
|
||||
|
||||
int
|
||||
_procsplhi(void)
|
||||
{
|
||||
int s;
|
||||
Proc *p;
|
||||
|
||||
p = _threadgetproc();
|
||||
s = p->splhi;
|
||||
p->splhi = 1;
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
_procsplx(int s)
|
||||
{
|
||||
Proc *p;
|
||||
|
||||
p = _threadgetproc();
|
||||
p->splhi = s;
|
||||
if(s)
|
||||
return;
|
||||
if(p->pending)
|
||||
delayednotes(p, nil);
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue