Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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