Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/planix-v0/sys/src/libthread/note.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
	int (*fn)(void*, char*);
56
 
57
	if(!p->pending)
58
		return;
59
 
60
	p->pending = 0;
61
	for(n=notes; n<enotes; n++){
62
		if(n->proc == p){
63
			for(i=0; i<NFN; i++){
64
				if(onnotepid[i]!=p->pid || (fn = onnote[i])==nil)
65
					continue;
66
				if((*fn)(v, n->s))
67
					break;
68
			}
69
			if(i==NFN){
70
				_threaddebug(DBGNOTE, "Unhandled note %s, proc %p\n", n->s, p);
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
}
82
 
83
void
84
_threadnote(void *v, char *s)
85
{
86
	Proc *p;
87
	Note *n;
88
 
89
	_threaddebug(DBGNOTE, "Got note %s", s);
90
	if(strncmp(s, "sys:", 4) == 0)
91
		noted(NDFLT);
92
 
93
	if(_threadexitsallstatus){
94
		_threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'\n", _threadexitsallstatus);
95
		_exits(_threadexitsallstatus);
96
	}
97
 
98
	if(strcmp(s, "threadint")==0)
99
		noted(NCONT);
100
 
101
	p = _threadgetproc();
102
	if(p == nil)
103
		noted(NDFLT);
104
 
105
	for(n=notes; n<enotes; n++)
106
		if(canlock(&n->inuse))
107
			break;
108
	if(n==enotes)
109
		sysfatal("libthread: too many delayed notes");
110
	utfecpy(n->s, n->s+ERRMAX, s);
111
	n->proc = p;
112
	p->pending = 1;
113
	if(!p->splhi)
114
		delayednotes(p, v);
115
	noted(NCONT);
116
}
117
 
118
int
119
_procsplhi(void)
120
{
121
	int s;
122
	Proc *p;
123
 
124
	p = _threadgetproc();
125
	s = p->splhi;
126
	p->splhi = 1;
127
	return s;
128
}
129
 
130
void
131
_procsplx(int s)
132
{
133
	Proc *p;
134
 
135
	p = _threadgetproc();
136
	p->splhi = s;
137
	if(s)
138
		return;
139
	if(p->pending)
140
		delayednotes(p, nil);
141
}
142