xref: /plan9/sys/src/cmd/unix/drawterm/kern/pgrp.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1 #include	"u.h"
2 #include	"lib.h"
3 #include	"dat.h"
4 #include	"fns.h"
5 #include	"error.h"
6 
7 static Ref pgrpid;
8 static Ref mountid;
9 
10 #ifdef NOTDEF
11 void
pgrpnote(ulong noteid,char * a,long n,int flag)12 pgrpnote(ulong noteid, char *a, long n, int flag)
13 {
14 	Proc *p, *ep;
15 	char buf[ERRMAX];
16 
17 	if(n >= ERRMAX-1)
18 		error(Etoobig);
19 
20 	memmove(buf, a, n);
21 	buf[n] = 0;
22 	p = proctab(0);
23 	ep = p+conf.nproc;
24 	for(; p < ep; p++) {
25 		if(p->state == Dead)
26 			continue;
27 		if(up != p && p->noteid == noteid && p->kp == 0) {
28 			qlock(&p->debug);
29 			if(p->pid == 0 || p->noteid != noteid){
30 				qunlock(&p->debug);
31 				continue;
32 			}
33 			if(!waserror()) {
34 				postnote(p, 0, buf, flag);
35 				poperror();
36 			}
37 			qunlock(&p->debug);
38 		}
39 	}
40 }
41 #endif
42 
43 Pgrp*
newpgrp(void)44 newpgrp(void)
45 {
46 	Pgrp *p;
47 
48 	p = smalloc(sizeof(Pgrp));
49 	p->ref.ref = 1;
50 	p->pgrpid = incref(&pgrpid);
51 	return p;
52 }
53 
54 Rgrp*
newrgrp(void)55 newrgrp(void)
56 {
57 	Rgrp *r;
58 
59 	r = smalloc(sizeof(Rgrp));
60 	r->ref.ref = 1;
61 	return r;
62 }
63 
64 void
closergrp(Rgrp * r)65 closergrp(Rgrp *r)
66 {
67 	if(decref(&r->ref) == 0)
68 		free(r);
69 }
70 
71 void
closepgrp(Pgrp * p)72 closepgrp(Pgrp *p)
73 {
74 	Mhead **h, **e, *f, *next;
75 
76 	if(decref(&p->ref) != 0)
77 		return;
78 
79 	qlock(&p->debug);
80 	wlock(&p->ns);
81 	p->pgrpid = -1;
82 
83 	e = &p->mnthash[MNTHASH];
84 	for(h = p->mnthash; h < e; h++) {
85 		for(f = *h; f; f = next) {
86 			wlock(&f->lock);
87 			cclose(f->from);
88 			mountfree(f->mount);
89 			f->mount = nil;
90 			next = f->hash;
91 			wunlock(&f->lock);
92 			putmhead(f);
93 		}
94 	}
95 	wunlock(&p->ns);
96 	qunlock(&p->debug);
97 	free(p);
98 }
99 
100 void
pgrpinsert(Mount ** order,Mount * m)101 pgrpinsert(Mount **order, Mount *m)
102 {
103 	Mount *f;
104 
105 	m->order = 0;
106 	if(*order == 0) {
107 		*order = m;
108 		return;
109 	}
110 	for(f = *order; f; f = f->order) {
111 		if(m->mountid < f->mountid) {
112 			m->order = f;
113 			*order = m;
114 			return;
115 		}
116 		order = &f->order;
117 	}
118 	*order = m;
119 }
120 
121 /*
122  * pgrpcpy MUST preserve the mountid allocation order of the parent group
123  */
124 void
pgrpcpy(Pgrp * to,Pgrp * from)125 pgrpcpy(Pgrp *to, Pgrp *from)
126 {
127 	int i;
128 	Mount *n, *m, **link, *order;
129 	Mhead *f, **tom, **l, *mh;
130 
131 	wlock(&from->ns);
132 	order = 0;
133 	tom = to->mnthash;
134 	for(i = 0; i < MNTHASH; i++) {
135 		l = tom++;
136 		for(f = from->mnthash[i]; f; f = f->hash) {
137 			rlock(&f->lock);
138 			mh = newmhead(f->from);
139 			*l = mh;
140 			l = &mh->hash;
141 			link = &mh->mount;
142 			for(m = f->mount; m; m = m->next) {
143 				n = newmount(mh, m->to, m->mflag, m->spec);
144 				m->copy = n;
145 				pgrpinsert(&order, m);
146 				*link = n;
147 				link = &n->next;
148 			}
149 			runlock(&f->lock);
150 		}
151 	}
152 	/*
153 	 * Allocate mount ids in the same sequence as the parent group
154 	 */
155 	lock(&mountid.lk);
156 	for(m = order; m; m = m->order)
157 		m->copy->mountid = mountid.ref++;
158 	unlock(&mountid.lk);
159 	wunlock(&from->ns);
160 }
161 
162 Fgrp*
dupfgrp(Fgrp * f)163 dupfgrp(Fgrp *f)
164 {
165 	Fgrp *new;
166 	Chan *c;
167 	int i;
168 
169 	new = smalloc(sizeof(Fgrp));
170 	if(f == nil){
171 		new->fd = smalloc(DELTAFD*sizeof(Chan*));
172 		new->nfd = DELTAFD;
173 		new->ref.ref = 1;
174 		return new;
175 	}
176 
177 	lock(&f->ref.lk);
178 	/* Make new fd list shorter if possible, preserving quantization */
179 	new->nfd = f->maxfd+1;
180 	i = new->nfd%DELTAFD;
181 	if(i != 0)
182 		new->nfd += DELTAFD - i;
183 	new->fd = malloc(new->nfd*sizeof(Chan*));
184 	if(new->fd == 0){
185 		unlock(&f->ref.lk);
186 		error("no memory for fgrp");
187 	}
188 	new->ref.ref = 1;
189 
190 	new->maxfd = f->maxfd;
191 	for(i = 0; i <= f->maxfd; i++) {
192 		if((c = f->fd[i])){
193 			incref(&c->ref);
194 			new->fd[i] = c;
195 		}
196 	}
197 	unlock(&f->ref.lk);
198 
199 	return new;
200 }
201 
202 void
closefgrp(Fgrp * f)203 closefgrp(Fgrp *f)
204 {
205 	int i;
206 	Chan *c;
207 
208 	if(f == 0)
209 		return;
210 
211 	if(decref(&f->ref) != 0)
212 		return;
213 
214 	for(i = 0; i <= f->maxfd; i++)
215 		if((c = f->fd[i]))
216 			cclose(c);
217 
218 	free(f->fd);
219 	free(f);
220 }
221 
222 Mount*
newmount(Mhead * mh,Chan * to,int flag,char * spec)223 newmount(Mhead *mh, Chan *to, int flag, char *spec)
224 {
225 	Mount *m;
226 
227 	m = smalloc(sizeof(Mount));
228 	m->to = to;
229 	m->head = mh;
230 	incref(&to->ref);
231 	m->mountid = incref(&mountid);
232 	m->mflag = flag;
233 	if(spec != 0)
234 		kstrdup(&m->spec, spec);
235 
236 	return m;
237 }
238 
239 void
mountfree(Mount * m)240 mountfree(Mount *m)
241 {
242 	Mount *f;
243 
244 	while(m) {
245 		f = m->next;
246 		cclose(m->to);
247 		m->mountid = 0;
248 		free(m->spec);
249 		free(m);
250 		m = f;
251 	}
252 }
253 
254 #ifdef NOTDEF
255 void
resrcwait(char * reason)256 resrcwait(char *reason)
257 {
258 	char *p;
259 
260 	if(up == 0)
261 		panic("resrcwait");
262 
263 	p = up->psstate;
264 	if(reason) {
265 		up->psstate = reason;
266 		print("%s\n", reason);
267 	}
268 
269 	tsleep(&up->sleep, return0, 0, 300);
270 	up->psstate = p;
271 }
272 #endif
273