Blame


1 2517c38a 2004-02-29 devnull #define NOPLAN9DEFINES
2 2517c38a 2004-02-29 devnull #include <u.h>
3 2517c38a 2004-02-29 devnull #include <libc.h>
4 2517c38a 2004-02-29 devnull #include <thread.h>
5 c4097c29 2004-05-11 devnull #include "threadimpl.h"
6 2517c38a 2004-02-29 devnull #include <errno.h>
7 2517c38a 2004-02-29 devnull #include <unistd.h>
8 2517c38a 2004-02-29 devnull #include <fcntl.h>
9 53dbac94 2004-03-02 devnull
10 53dbac94 2004-03-02 devnull #define debugpoll 0
11 53dbac94 2004-03-02 devnull
12 53dbac94 2004-03-02 devnull #ifdef __APPLE__
13 53dbac94 2004-03-02 devnull #include <sys/time.h>
14 53dbac94 2004-03-02 devnull enum { POLLIN=1, POLLOUT=2, POLLERR=4 };
15 53dbac94 2004-03-02 devnull struct pollfd
16 53dbac94 2004-03-02 devnull {
17 53dbac94 2004-03-02 devnull int fd;
18 53dbac94 2004-03-02 devnull int events;
19 53dbac94 2004-03-02 devnull int revents;
20 53dbac94 2004-03-02 devnull };
21 53dbac94 2004-03-02 devnull
22 53dbac94 2004-03-02 devnull int
23 53dbac94 2004-03-02 devnull poll(struct pollfd *p, int np, int ms)
24 53dbac94 2004-03-02 devnull {
25 53dbac94 2004-03-02 devnull int i, maxfd, n;
26 53dbac94 2004-03-02 devnull struct timeval tv, *tvp;
27 53dbac94 2004-03-02 devnull fd_set rfd, wfd, efd;
28 53dbac94 2004-03-02 devnull
29 53dbac94 2004-03-02 devnull maxfd = -1;
30 53dbac94 2004-03-02 devnull FD_ZERO(&rfd);
31 53dbac94 2004-03-02 devnull FD_ZERO(&wfd);
32 53dbac94 2004-03-02 devnull FD_ZERO(&efd);
33 53dbac94 2004-03-02 devnull for(i=0; i<np; i++){
34 53dbac94 2004-03-02 devnull p[i].revents = 0;
35 53dbac94 2004-03-02 devnull if(p[i].fd == -1)
36 53dbac94 2004-03-02 devnull continue;
37 53dbac94 2004-03-02 devnull if(p[i].fd > maxfd)
38 53dbac94 2004-03-02 devnull maxfd = p[i].fd;
39 53dbac94 2004-03-02 devnull if(p[i].events & POLLIN)
40 53dbac94 2004-03-02 devnull FD_SET(p[i].fd, &rfd);
41 53dbac94 2004-03-02 devnull if(p[i].events & POLLOUT)
42 53dbac94 2004-03-02 devnull FD_SET(p[i].fd, &wfd);
43 53dbac94 2004-03-02 devnull FD_SET(p[i].fd, &efd);
44 53dbac94 2004-03-02 devnull }
45 53dbac94 2004-03-02 devnull
46 53dbac94 2004-03-02 devnull if(ms != -1){
47 53dbac94 2004-03-02 devnull tv.tv_usec = (ms%1000)*1000;
48 53dbac94 2004-03-02 devnull tv.tv_sec = ms/1000;
49 53dbac94 2004-03-02 devnull tvp = &tv;
50 53dbac94 2004-03-02 devnull }else
51 53dbac94 2004-03-02 devnull tvp = nil;
52 53dbac94 2004-03-02 devnull
53 53dbac94 2004-03-02 devnull if(debugpoll){
54 53dbac94 2004-03-02 devnull fprint(2, "select %d:", maxfd+1);
55 53dbac94 2004-03-02 devnull for(i=0; i<=maxfd; i++){
56 53dbac94 2004-03-02 devnull if(FD_ISSET(i, &rfd))
57 53dbac94 2004-03-02 devnull fprint(2, " r%d", i);
58 53dbac94 2004-03-02 devnull if(FD_ISSET(i, &wfd))
59 53dbac94 2004-03-02 devnull fprint(2, " w%d", i);
60 53dbac94 2004-03-02 devnull if(FD_ISSET(i, &efd))
61 53dbac94 2004-03-02 devnull fprint(2, " e%d", i);
62 53dbac94 2004-03-02 devnull }
63 53dbac94 2004-03-02 devnull fprint(2, "; tp=%p, t=%d.%d\n", tvp, tv.tv_sec, tv.tv_usec);
64 53dbac94 2004-03-02 devnull }
65 2517c38a 2004-02-29 devnull
66 53dbac94 2004-03-02 devnull n = select(maxfd+1, &rfd, &wfd, &efd, tvp);
67 53dbac94 2004-03-02 devnull
68 53dbac94 2004-03-02 devnull if(n <= 0)
69 53dbac94 2004-03-02 devnull return n;
70 53dbac94 2004-03-02 devnull
71 53dbac94 2004-03-02 devnull for(i=0; i<np; i++){
72 53dbac94 2004-03-02 devnull if(p[i].fd == -1)
73 53dbac94 2004-03-02 devnull continue;
74 53dbac94 2004-03-02 devnull if(FD_ISSET(p[i].fd, &rfd))
75 53dbac94 2004-03-02 devnull p[i].revents |= POLLIN;
76 53dbac94 2004-03-02 devnull if(FD_ISSET(p[i].fd, &wfd))
77 53dbac94 2004-03-02 devnull p[i].revents |= POLLOUT;
78 53dbac94 2004-03-02 devnull if(FD_ISSET(p[i].fd, &efd))
79 53dbac94 2004-03-02 devnull p[i].revents |= POLLERR;
80 53dbac94 2004-03-02 devnull }
81 53dbac94 2004-03-02 devnull return n;
82 53dbac94 2004-03-02 devnull }
83 53dbac94 2004-03-02 devnull
84 53dbac94 2004-03-02 devnull #else
85 53dbac94 2004-03-02 devnull #include <poll.h>
86 53dbac94 2004-03-02 devnull #endif
87 53dbac94 2004-03-02 devnull
88 2517c38a 2004-02-29 devnull /*
89 2517c38a 2004-02-29 devnull * Poll file descriptors in an idle loop.
90 2517c38a 2004-02-29 devnull */
91 2517c38a 2004-02-29 devnull
92 2517c38a 2004-02-29 devnull typedef struct Poll Poll;
93 2517c38a 2004-02-29 devnull
94 2517c38a 2004-02-29 devnull struct Poll
95 2517c38a 2004-02-29 devnull {
96 2517c38a 2004-02-29 devnull Channel *c; /* for sending back */
97 2517c38a 2004-02-29 devnull };
98 2517c38a 2004-02-29 devnull
99 2517c38a 2004-02-29 devnull static Channel *sleepchan[64];
100 2517c38a 2004-02-29 devnull static int sleeptime[64];
101 2517c38a 2004-02-29 devnull static int nsleep;
102 2517c38a 2004-02-29 devnull
103 2517c38a 2004-02-29 devnull static struct pollfd pfd[64];
104 2517c38a 2004-02-29 devnull static struct Poll polls[64];
105 2517c38a 2004-02-29 devnull static int npoll;
106 2517c38a 2004-02-29 devnull
107 2517c38a 2004-02-29 devnull static void
108 2517c38a 2004-02-29 devnull pollidle(void *v)
109 2517c38a 2004-02-29 devnull {
110 2517c38a 2004-02-29 devnull int i, n, t;
111 2517c38a 2004-02-29 devnull uint now;
112 2517c38a 2004-02-29 devnull
113 2517c38a 2004-02-29 devnull for(;; yield()){
114 53dbac94 2004-03-02 devnull if(debugpoll) fprint(2, "poll %d:", npoll);
115 2517c38a 2004-02-29 devnull for(i=0; i<npoll; i++){
116 53dbac94 2004-03-02 devnull if(debugpoll) fprint(2, " %d%c", pfd[i].fd, pfd[i].events==POLLIN ? 'r' : 'w');
117 2517c38a 2004-02-29 devnull pfd[i].revents = 0;
118 2517c38a 2004-02-29 devnull }
119 2517c38a 2004-02-29 devnull t = -1;
120 53dbac94 2004-03-02 devnull now = p9nsec()/1000000;
121 2517c38a 2004-02-29 devnull for(i=0; i<nsleep; i++){
122 2517c38a 2004-02-29 devnull n = sleeptime[i] - now;
123 53dbac94 2004-03-02 devnull if(debugpoll) fprint(2, " s%d", n);
124 2517c38a 2004-02-29 devnull if(n < 0)
125 2517c38a 2004-02-29 devnull n = 0;
126 2517c38a 2004-02-29 devnull if(t == -1 || n < t)
127 2517c38a 2004-02-29 devnull t = n;
128 2517c38a 2004-02-29 devnull }
129 53dbac94 2004-03-02 devnull if(debugpoll) fprint(2, "; t=%d\n", t);
130 2517c38a 2004-02-29 devnull
131 2517c38a 2004-02-29 devnull n = poll(pfd, npoll, t);
132 2517c38a 2004-02-29 devnull //fprint(2, "poll ret %d:", n);
133 2517c38a 2004-02-29 devnull now = p9nsec()/1000000;
134 2517c38a 2004-02-29 devnull for(i=0; i<nsleep; i++){
135 2517c38a 2004-02-29 devnull if((int)(sleeptime[i] - now) < 0){
136 2517c38a 2004-02-29 devnull nbsendul(sleepchan[i], 0);
137 2517c38a 2004-02-29 devnull nsleep--;
138 2517c38a 2004-02-29 devnull sleepchan[i] = sleepchan[nsleep];
139 2517c38a 2004-02-29 devnull sleeptime[i] = sleeptime[nsleep];
140 2517c38a 2004-02-29 devnull i--;
141 2517c38a 2004-02-29 devnull }
142 2517c38a 2004-02-29 devnull }
143 2517c38a 2004-02-29 devnull
144 2517c38a 2004-02-29 devnull if(n <= 0)
145 2517c38a 2004-02-29 devnull continue;
146 2517c38a 2004-02-29 devnull for(i=0; i<npoll; i++)
147 2517c38a 2004-02-29 devnull if(pfd[i].fd != -1 && pfd[i].revents){
148 2517c38a 2004-02-29 devnull //fprint(2, " %d", pfd[i].fd);
149 2517c38a 2004-02-29 devnull pfd[i].fd = -1;
150 2517c38a 2004-02-29 devnull pfd[i].events = 0;
151 2517c38a 2004-02-29 devnull pfd[i].revents = 0;
152 4da83e7c 2004-03-05 devnull nbsendul(polls[i].c, 1);
153 4da83e7c 2004-03-05 devnull //fprint(2, " x%d", pfd[i].fd);
154 2517c38a 2004-02-29 devnull }
155 2517c38a 2004-02-29 devnull //fprint(2, "\n");
156 2517c38a 2004-02-29 devnull }
157 2517c38a 2004-02-29 devnull }
158 2517c38a 2004-02-29 devnull
159 2517c38a 2004-02-29 devnull void
160 2517c38a 2004-02-29 devnull threadfdwaitsetup(void)
161 2517c38a 2004-02-29 devnull {
162 2517c38a 2004-02-29 devnull static int setup = 0;
163 2517c38a 2004-02-29 devnull
164 2517c38a 2004-02-29 devnull if(!setup){
165 2517c38a 2004-02-29 devnull setup = 1;
166 2517c38a 2004-02-29 devnull threadcreateidle(pollidle, nil, 16384);
167 2517c38a 2004-02-29 devnull }
168 2517c38a 2004-02-29 devnull }
169 2517c38a 2004-02-29 devnull
170 2517c38a 2004-02-29 devnull void
171 c91bd328 2004-03-05 devnull _threadfdwait(int fd, int rw, ulong pc)
172 2517c38a 2004-02-29 devnull {
173 2517c38a 2004-02-29 devnull int i;
174 2517c38a 2004-02-29 devnull
175 2517c38a 2004-02-29 devnull struct {
176 2517c38a 2004-02-29 devnull Channel c;
177 2517c38a 2004-02-29 devnull ulong x;
178 1a8f27c3 2004-05-14 devnull Alt *qentry[2];
179 2517c38a 2004-02-29 devnull } s;
180 2517c38a 2004-02-29 devnull
181 2517c38a 2004-02-29 devnull threadfdwaitsetup();
182 2517c38a 2004-02-29 devnull chaninit(&s.c, sizeof(ulong), 1);
183 c4097c29 2004-05-11 devnull s.c.qentry = (volatile Alt**)s.qentry;
184 c4097c29 2004-05-11 devnull s.c.nentry = 2;
185 c4097c29 2004-05-11 devnull memset(s.qentry, 0, sizeof s.qentry);
186 2517c38a 2004-02-29 devnull for(i=0; i<npoll; i++)
187 2517c38a 2004-02-29 devnull if(pfd[i].fd == -1)
188 2517c38a 2004-02-29 devnull break;
189 2517c38a 2004-02-29 devnull if(i==npoll){
190 2517c38a 2004-02-29 devnull if(npoll >= nelem(polls)){
191 2517c38a 2004-02-29 devnull fprint(2, "Too many polled fds.\n");
192 2517c38a 2004-02-29 devnull abort();
193 2517c38a 2004-02-29 devnull }
194 2517c38a 2004-02-29 devnull npoll++;
195 2517c38a 2004-02-29 devnull }
196 2517c38a 2004-02-29 devnull
197 2517c38a 2004-02-29 devnull pfd[i].fd = fd;
198 2517c38a 2004-02-29 devnull pfd[i].events = rw=='r' ? POLLIN : POLLOUT;
199 2517c38a 2004-02-29 devnull polls[i].c = &s.c;
200 4da83e7c 2004-03-05 devnull if(0) fprint(2, "%s [%3d] fdwait %d %c list *0x%lux\n",
201 c91bd328 2004-03-05 devnull argv0, threadid(), fd, rw, pc);
202 2517c38a 2004-02-29 devnull recvul(&s.c);
203 2517c38a 2004-02-29 devnull }
204 2517c38a 2004-02-29 devnull
205 2517c38a 2004-02-29 devnull void
206 c91bd328 2004-03-05 devnull threadfdwait(int fd, int rw)
207 c91bd328 2004-03-05 devnull {
208 c91bd328 2004-03-05 devnull _threadfdwait(fd, rw, getcallerpc(&fd));
209 c91bd328 2004-03-05 devnull }
210 c91bd328 2004-03-05 devnull
211 c91bd328 2004-03-05 devnull void
212 2517c38a 2004-02-29 devnull threadsleep(int ms)
213 2517c38a 2004-02-29 devnull {
214 2517c38a 2004-02-29 devnull struct {
215 2517c38a 2004-02-29 devnull Channel c;
216 2517c38a 2004-02-29 devnull ulong x;
217 1a8f27c3 2004-05-14 devnull Alt *qentry[2];
218 2517c38a 2004-02-29 devnull } s;
219 2517c38a 2004-02-29 devnull
220 2517c38a 2004-02-29 devnull threadfdwaitsetup();
221 2517c38a 2004-02-29 devnull chaninit(&s.c, sizeof(ulong), 1);
222 1a8f27c3 2004-05-14 devnull s.c.qentry = (volatile Alt**)s.qentry;
223 1a8f27c3 2004-05-14 devnull s.c.nentry = 2;
224 1a8f27c3 2004-05-14 devnull memset(s.qentry, 0, sizeof s.qentry);
225 1a8f27c3 2004-05-14 devnull
226 2517c38a 2004-02-29 devnull sleepchan[nsleep] = &s.c;
227 2517c38a 2004-02-29 devnull sleeptime[nsleep++] = p9nsec()/1000000+ms;
228 2517c38a 2004-02-29 devnull recvul(&s.c);
229 2517c38a 2004-02-29 devnull }
230 2517c38a 2004-02-29 devnull
231 2517c38a 2004-02-29 devnull void
232 2517c38a 2004-02-29 devnull threadfdnoblock(int fd)
233 2517c38a 2004-02-29 devnull {
234 2517c38a 2004-02-29 devnull fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)|O_NONBLOCK);
235 2517c38a 2004-02-29 devnull }
236 2517c38a 2004-02-29 devnull
237 2517c38a 2004-02-29 devnull long
238 2517c38a 2004-02-29 devnull threadread(int fd, void *a, long n)
239 2517c38a 2004-02-29 devnull {
240 2517c38a 2004-02-29 devnull int nn;
241 2517c38a 2004-02-29 devnull
242 2517c38a 2004-02-29 devnull threadfdnoblock(fd);
243 2517c38a 2004-02-29 devnull again:
244 c6687d45 2004-09-21 devnull /*
245 c6687d45 2004-09-21 devnull * Always call wait (i.e. don't optimistically try the read)
246 c6687d45 2004-09-21 devnull * so that the scheduler gets a chance to run other threads.
247 c6687d45 2004-09-21 devnull */
248 c6687d45 2004-09-21 devnull _threadfdwait(fd, 'r', getcallerpc(&fd));
249 2b4b2ae1 2004-04-21 devnull errno = 0;
250 2517c38a 2004-02-29 devnull nn = read(fd, a, n);
251 2b4b2ae1 2004-04-21 devnull if(nn <= 0){
252 c6687d45 2004-09-21 devnull if(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
253 2517c38a 2004-02-29 devnull goto again;
254 2517c38a 2004-02-29 devnull }
255 2517c38a 2004-02-29 devnull return nn;
256 2517c38a 2004-02-29 devnull }
257 2517c38a 2004-02-29 devnull
258 2517c38a 2004-02-29 devnull int
259 2517c38a 2004-02-29 devnull threadrecvfd(int fd)
260 2517c38a 2004-02-29 devnull {
261 2517c38a 2004-02-29 devnull int nn;
262 2517c38a 2004-02-29 devnull
263 2517c38a 2004-02-29 devnull threadfdnoblock(fd);
264 2517c38a 2004-02-29 devnull again:
265 c6687d45 2004-09-21 devnull /*
266 c6687d45 2004-09-21 devnull * Always call wait (i.e. don't optimistically try the recvfd)
267 c6687d45 2004-09-21 devnull * so that the scheduler gets a chance to run other threads.
268 c6687d45 2004-09-21 devnull */
269 c6687d45 2004-09-21 devnull _threadfdwait(fd, 'r', getcallerpc(&fd));
270 2517c38a 2004-02-29 devnull nn = recvfd(fd);
271 2517c38a 2004-02-29 devnull if(nn < 0){
272 c6687d45 2004-09-21 devnull if(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
273 2517c38a 2004-02-29 devnull goto again;
274 2517c38a 2004-02-29 devnull }
275 2517c38a 2004-02-29 devnull return nn;
276 2517c38a 2004-02-29 devnull }
277 2517c38a 2004-02-29 devnull
278 2517c38a 2004-02-29 devnull int
279 2517c38a 2004-02-29 devnull threadsendfd(int fd, int sfd)
280 2517c38a 2004-02-29 devnull {
281 2517c38a 2004-02-29 devnull int nn;
282 2517c38a 2004-02-29 devnull
283 2517c38a 2004-02-29 devnull threadfdnoblock(fd);
284 2517c38a 2004-02-29 devnull again:
285 c6687d45 2004-09-21 devnull /*
286 c6687d45 2004-09-21 devnull * Always call wait (i.e. don't optimistically try the sendfd)
287 c6687d45 2004-09-21 devnull * so that the scheduler gets a chance to run other threads.
288 c6687d45 2004-09-21 devnull */
289 c6687d45 2004-09-21 devnull _threadfdwait(fd, 'w', getcallerpc(&fd));
290 2517c38a 2004-02-29 devnull nn = sendfd(fd, sfd);
291 2517c38a 2004-02-29 devnull if(nn < 0){
292 c6687d45 2004-09-21 devnull if(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
293 2517c38a 2004-02-29 devnull goto again;
294 2517c38a 2004-02-29 devnull }
295 2517c38a 2004-02-29 devnull return nn;
296 2517c38a 2004-02-29 devnull }
297 2517c38a 2004-02-29 devnull
298 2517c38a 2004-02-29 devnull long
299 2517c38a 2004-02-29 devnull threadreadn(int fd, void *a, long n)
300 2517c38a 2004-02-29 devnull {
301 2517c38a 2004-02-29 devnull int tot, nn;
302 2517c38a 2004-02-29 devnull
303 2517c38a 2004-02-29 devnull for(tot = 0; tot<n; tot+=nn){
304 2517c38a 2004-02-29 devnull nn = threadread(fd, (char*)a+tot, n-tot);
305 2517c38a 2004-02-29 devnull if(nn <= 0){
306 2517c38a 2004-02-29 devnull if(tot == 0)
307 2517c38a 2004-02-29 devnull return nn;
308 2517c38a 2004-02-29 devnull return tot;
309 2517c38a 2004-02-29 devnull }
310 2517c38a 2004-02-29 devnull }
311 2517c38a 2004-02-29 devnull return tot;
312 2517c38a 2004-02-29 devnull }
313 2517c38a 2004-02-29 devnull
314 2517c38a 2004-02-29 devnull long
315 2517c38a 2004-02-29 devnull _threadwrite(int fd, const void *a, long n)
316 2517c38a 2004-02-29 devnull {
317 2517c38a 2004-02-29 devnull int nn;
318 2517c38a 2004-02-29 devnull
319 2517c38a 2004-02-29 devnull threadfdnoblock(fd);
320 2517c38a 2004-02-29 devnull again:
321 c6687d45 2004-09-21 devnull /*
322 c6687d45 2004-09-21 devnull * Always call wait (i.e. don't optimistically try the write)
323 c6687d45 2004-09-21 devnull * so that the scheduler gets a chance to run other threads.
324 c6687d45 2004-09-21 devnull */
325 c6687d45 2004-09-21 devnull _threadfdwait(fd, 'w', getcallerpc(&fd));
326 2517c38a 2004-02-29 devnull nn = write(fd, a, n);
327 2517c38a 2004-02-29 devnull if(nn < 0){
328 c6687d45 2004-09-21 devnull if(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
329 2517c38a 2004-02-29 devnull goto again;
330 2517c38a 2004-02-29 devnull }
331 2517c38a 2004-02-29 devnull return nn;
332 2517c38a 2004-02-29 devnull }
333 2517c38a 2004-02-29 devnull
334 2517c38a 2004-02-29 devnull long
335 2517c38a 2004-02-29 devnull threadwrite(int fd, const void *a, long n)
336 2517c38a 2004-02-29 devnull {
337 2517c38a 2004-02-29 devnull int tot, nn;
338 2517c38a 2004-02-29 devnull
339 2517c38a 2004-02-29 devnull for(tot = 0; tot<n; tot+=nn){
340 2517c38a 2004-02-29 devnull nn = _threadwrite(fd, (char*)a+tot, n-tot);
341 2517c38a 2004-02-29 devnull if(nn <= 0){
342 2517c38a 2004-02-29 devnull if(tot == 0)
343 2517c38a 2004-02-29 devnull return nn;
344 2517c38a 2004-02-29 devnull return tot;
345 2517c38a 2004-02-29 devnull }
346 2517c38a 2004-02-29 devnull }
347 2517c38a 2004-02-29 devnull return tot;
348 2517c38a 2004-02-29 devnull }
349 9a4289cf 2004-06-09 devnull
350 9a4289cf 2004-06-09 devnull int
351 9a4289cf 2004-06-09 devnull threadannounce(char *addr, char *dir)
352 9a4289cf 2004-06-09 devnull {
353 9a4289cf 2004-06-09 devnull return p9announce(addr, dir);
354 9a4289cf 2004-06-09 devnull }
355 9a4289cf 2004-06-09 devnull
356 9a4289cf 2004-06-09 devnull int
357 9a4289cf 2004-06-09 devnull threadlisten(char *dir, char *newdir)
358 9a4289cf 2004-06-09 devnull {
359 9a4289cf 2004-06-09 devnull int fd, ret;
360 9a4289cf 2004-06-09 devnull extern int _p9netfd(char*);
361 2517c38a 2004-02-29 devnull
362 9a4289cf 2004-06-09 devnull fd = _p9netfd(dir);
363 9a4289cf 2004-06-09 devnull if(fd < 0){
364 9a4289cf 2004-06-09 devnull werrstr("bad 'directory' in listen: %s", dir);
365 9a4289cf 2004-06-09 devnull return -1;
366 9a4289cf 2004-06-09 devnull }
367 9a4289cf 2004-06-09 devnull threadfdnoblock(fd);
368 9a4289cf 2004-06-09 devnull while((ret = p9listen(dir, newdir)) < 0 && errno==EAGAIN)
369 9a4289cf 2004-06-09 devnull _threadfdwait(fd, 'r', getcallerpc(&dir));
370 9a4289cf 2004-06-09 devnull return ret;
371 9a4289cf 2004-06-09 devnull }
372 9a4289cf 2004-06-09 devnull
373 9a4289cf 2004-06-09 devnull int
374 9a4289cf 2004-06-09 devnull threadaccept(int cfd, char *dir)
375 9a4289cf 2004-06-09 devnull {
376 9a4289cf 2004-06-09 devnull return p9accept(cfd, dir);
377 9a4289cf 2004-06-09 devnull }
378 9a4289cf 2004-06-09 devnull