merge libminlib with libc
[minix3.git] / minix / servers / vfs / select.c
blob5bf2a1171c553b3d01f9cb67c15f99eb08db007a
1 /* Implement entry point to select system call.
3 * The entry points into this file are
4 * do_select: perform the SELECT system call
5 * select_callback: notify select system of possible fd operation
6 * select_unsuspend_by_endpt: cancel a blocking select on exiting driver
8 * The select code uses minimal locking, so that the replies from character
9 * drivers can be processed without blocking. Filps are locked only for pipes.
10 * We make the assumption that any other structures and fields are safe to
11 * check (and possibly change) as long as we know that a process is blocked on
12 * a select(2) call, meaning that all involved filps are guaranteed to stay
13 * open until either we finish the select call, it the process gets interrupted
14 * by a signal.
17 #include "fs.h"
18 #include <sys/fcntl.h>
19 #include <sys/time.h>
20 #include <sys/select.h>
21 #include <sys/stat.h>
22 #include <minix/callnr.h>
23 #include <minix/u64.h>
24 #include <string.h>
25 #include <assert.h>
27 #include "file.h"
28 #include "vnode.h"
30 /* max. number of simultaneously pending select() calls */
31 #define MAXSELECTS 25
32 #define FROM_PROC 0
33 #define TO_PROC 1
35 static struct selectentry {
36 struct fproc *requestor; /* slot is free iff this is NULL */
37 endpoint_t req_endpt;
38 fd_set readfds, writefds, errorfds;
39 fd_set ready_readfds, ready_writefds, ready_errorfds;
40 fd_set *vir_readfds, *vir_writefds, *vir_errorfds;
41 struct filp *filps[OPEN_MAX];
42 int type[OPEN_MAX];
43 int nfds, nreadyfds;
44 int error;
45 char block;
46 char starting;
47 clock_t expiry;
48 minix_timer_t timer; /* if expiry > 0 */
49 } selecttab[MAXSELECTS];
51 static int copy_fdsets(struct selectentry *se, int nfds, int direction);
52 static void filp_status(struct filp *fp, int status);
53 static int is_deferred(struct selectentry *se);
54 static void restart_proc(struct selectentry *se);
55 static void ops2tab(int ops, int fd, struct selectentry *e);
56 static int is_regular_file(struct filp *f);
57 static int is_pipe(struct filp *f);
58 static int is_char_device(struct filp *f);
59 static void select_lock_filp(struct filp *f, int ops);
60 static int select_request_file(struct filp *f, int *ops, int block,
61 struct fproc *rfp);
62 static int select_request_char(struct filp *f, int *ops, int block,
63 struct fproc *rfp);
64 static int select_request_pipe(struct filp *f, int *ops, int block,
65 struct fproc *rfp);
66 static void select_cancel_all(struct selectentry *e);
67 static void select_cancel_filp(struct filp *f);
68 static void select_return(struct selectentry *);
69 static void select_restart_filps(void);
70 static int tab2ops(int fd, struct selectentry *e);
71 static void wipe_select(struct selectentry *s);
73 static struct fdtype {
74 int (*select_request)(struct filp *, int *ops, int block,
75 struct fproc *rfp);
76 int (*type_match)(struct filp *f);
77 } fdtypes[] = {
78 { select_request_char, is_char_device },
79 { select_request_file, is_regular_file },
80 { select_request_pipe, is_pipe },
82 #define SEL_FDS (sizeof(fdtypes) / sizeof(fdtypes[0]))
84 /*===========================================================================*
85 * do_select *
86 *===========================================================================*/
87 int do_select(void)
89 /* Implement the select(nfds, readfds, writefds, errorfds, timeout) system
90 * call. First we copy the arguments and verify their sanity. Then we check
91 * whether there are file descriptors that satisfy the select call right off
92 * the bat. If so, or if there are no ready file descriptors but the process
93 * requested to return immediately, we return the result. Otherwise we set a
94 * timeout and wait for either the file descriptors to become ready or the
95 * timer to go off. If no timeout value was provided, we wait indefinitely.
97 int r, nfds, do_timeout = 0, fd, s;
98 struct filp *f;
99 unsigned int type, ops;
100 struct timeval timeout;
101 struct selectentry *se;
102 vir_bytes vtimeout;
104 nfds = job_m_in.m_lc_vfs_select.nfds;
105 vtimeout = job_m_in.m_lc_vfs_select.timeout;
107 /* Sane amount of file descriptors? */
108 if (nfds < 0 || nfds > OPEN_MAX) return(EINVAL);
110 /* Find a slot to store this select request */
111 for (s = 0; s < MAXSELECTS; s++)
112 if (selecttab[s].requestor == NULL) /* Unused slot */
113 break;
114 if (s >= MAXSELECTS) return(ENOSPC);
116 se = &selecttab[s];
117 wipe_select(se); /* Clear results of previous usage */
118 se->requestor = fp;
119 se->req_endpt = who_e;
120 se->vir_readfds = job_m_in.m_lc_vfs_select.readfds;
121 se->vir_writefds = job_m_in.m_lc_vfs_select.writefds;
122 se->vir_errorfds = job_m_in.m_lc_vfs_select.errorfds;
124 /* Copy fdsets from the process */
125 if ((r = copy_fdsets(se, nfds, FROM_PROC)) != OK) {
126 se->requestor = NULL;
127 return(r);
130 /* Did the process set a timeout value? If so, retrieve it. */
131 if (vtimeout != 0) {
132 do_timeout = 1;
133 r = sys_datacopy_wrapper(who_e, vtimeout, SELF, (vir_bytes) &timeout,
134 sizeof(timeout));
135 if (r != OK) {
136 se->requestor = NULL;
137 return(r);
141 /* No nonsense in the timeval */
142 if (do_timeout && (timeout.tv_sec < 0 || timeout.tv_usec < 0)) {
143 se->requestor = NULL;
144 return(EINVAL);
147 /* If there is no timeout, we block forever. Otherwise, we block up to the
148 * specified time interval.
150 if (!do_timeout) /* No timeout value set */
151 se->block = 1;
152 else if (do_timeout && (timeout.tv_sec > 0 || timeout.tv_usec > 0))
153 se->block = 1;
154 else /* timeout set as (0,0) - this effects a poll */
155 se->block = 0;
156 se->expiry = 0; /* no timer set (yet) */
158 /* We are going to lock filps, and that means that while locking a second
159 * filp, we might already get the results for the first one. In that case,
160 * the incoming results must not cause the select call to finish prematurely.
162 se->starting = TRUE;
164 /* Verify that file descriptors are okay to select on */
165 for (fd = 0; fd < nfds; fd++) {
166 /* Because the select() interface implicitly includes file descriptors
167 * you might not want to select on, we have to figure out whether we're
168 * interested in them. Typically, these file descriptors include fd's
169 * inherited from the parent proc and file descriptors that have been
170 * close()d, but had a lower fd than one in the current set.
172 if (!(ops = tab2ops(fd, se)))
173 continue; /* No operations set; nothing to do for this fd */
175 /* Get filp belonging to this fd */
176 f = se->filps[fd] = get_filp(fd, VNODE_READ);
177 if (f == NULL) {
178 if (err_code == EBADF)
179 r = err_code;
180 else /* File descriptor is 'ready' to return EIO */
181 r = EINTR;
183 se->requestor = NULL;
184 return(r);
187 /* Check file types. According to POSIX 2008:
188 * "The pselect() and select() functions shall support regular files,
189 * terminal and pseudo-terminal devices, FIFOs, pipes, and sockets. The
190 * behavior of pselect() and select() on file descriptors that refer to
191 * other types of file is unspecified."
193 * In our case, terminal and pseudo-terminal devices are handled by the
194 * TTY major and sockets by either INET major (socket type AF_INET) or
195 * UDS major (socket type AF_UNIX). Additionally, we give other
196 * character drivers the chance to handle select for any of their
197 * device nodes. Some may not implement support for select and let
198 * libchardriver return EBADF, which we then pass to the calling
199 * process once we receive the reply.
201 se->type[fd] = -1;
202 for (type = 0; type < SEL_FDS; type++) {
203 if (fdtypes[type].type_match(f)) {
204 se->type[fd] = type;
205 se->nfds = fd+1;
206 se->filps[fd]->filp_selectors++;
207 break;
210 unlock_filp(f);
211 if (se->type[fd] == -1) { /* Type not found */
212 se->requestor = NULL;
213 return(EBADF);
217 /* Check all file descriptors in the set whether one is 'ready' now */
218 for (fd = 0; fd < nfds; fd++) {
219 /* Again, check for involuntarily selected fd's */
220 if (!(ops = tab2ops(fd, se)))
221 continue; /* No operations set; nothing to do for this fd */
223 /* File descriptors selected for reading that are not opened for
224 * reading should be marked as readable, as read calls would fail
225 * immediately. The same applies to writing.
227 f = se->filps[fd];
228 if ((ops & SEL_RD) && !(f->filp_mode & R_BIT)) {
229 ops2tab(SEL_RD, fd, se);
230 ops &= ~SEL_RD;
232 if ((ops & SEL_WR) && !(f->filp_mode & W_BIT)) {
233 ops2tab(SEL_WR, fd, se);
234 ops &= ~SEL_WR;
236 /* Test filp for select operations if not already done so. e.g.,
237 * processes sharing a filp and both doing a select on that filp. */
238 if ((f->filp_select_ops & ops) != ops) {
239 int wantops;
241 wantops = (f->filp_select_ops |= ops);
242 type = se->type[fd];
243 select_lock_filp(f, wantops);
244 r = fdtypes[type].select_request(f, &wantops, se->block, fp);
245 unlock_filp(f);
246 if (r != OK && r != SUSPEND) {
247 se->error = r;
248 break; /* Error or bogus return code; abort */
251 /* The select request above might have turned on/off some
252 * operations because they were 'ready' or not meaningful.
253 * Either way, we might have a result and we need to store them
254 * in the select table entry. */
255 if (wantops & ops) ops2tab(wantops, fd, se);
259 /* At this point there won't be any blocking calls anymore. */
260 se->starting = FALSE;
262 if ((se->nreadyfds > 0 || se->error != OK || !se->block) &&
263 !is_deferred(se)) {
264 /* An error occurred, or fd's were found that were ready to go right
265 * away, and/or we were instructed not to block at all. Must return
266 * immediately. Do not copy FD sets if an error occurred.
268 if (se->error != OK)
269 r = se->error;
270 else
271 r = copy_fdsets(se, se->nfds, TO_PROC);
272 select_cancel_all(se);
273 se->requestor = NULL;
275 if (r != OK)
276 return(r);
277 return(se->nreadyfds);
280 /* Convert timeval to ticks and set the timer. If it fails, undo
281 * all, return error.
283 if (do_timeout) {
284 int ticks;
285 /* Open Group:
286 * "If the requested timeout interval requires a finer
287 * granularity than the implementation supports, the
288 * actual timeout interval shall be rounded up to the next
289 * supported value."
291 #define USECPERSEC 1000000
292 while(timeout.tv_usec >= USECPERSEC) {
293 /* this is to avoid overflow with *system_hz below */
294 timeout.tv_usec -= USECPERSEC;
295 timeout.tv_sec++;
297 ticks = timeout.tv_sec * system_hz +
298 (timeout.tv_usec * system_hz + USECPERSEC-1) / USECPERSEC;
299 se->expiry = ticks;
300 set_timer(&se->timer, ticks, select_timeout_check, s);
303 /* process now blocked */
304 suspend(FP_BLOCKED_ON_SELECT);
305 return(SUSPEND);
308 /*===========================================================================*
309 * is_deferred *
310 *===========================================================================*/
311 static int is_deferred(struct selectentry *se)
313 /* Find out whether this select has pending initial replies */
315 int fd;
316 struct filp *f;
318 /* The select call must have finished its initialization at all. */
319 if (se->starting) return(TRUE);
321 for (fd = 0; fd < se->nfds; fd++) {
322 if ((f = se->filps[fd]) == NULL) continue;
323 if (f->filp_select_flags & (FSF_UPDATE|FSF_BUSY)) return(TRUE);
326 return(FALSE);
330 /*===========================================================================*
331 * is_regular_file *
332 *===========================================================================*/
333 static int is_regular_file(struct filp *f)
335 return(f && f->filp_vno && S_ISREG(f->filp_vno->v_mode));
338 /*===========================================================================*
339 * is_pipe *
340 *===========================================================================*/
341 static int is_pipe(struct filp *f)
343 /* Recognize either anonymous pipe or named pipe (FIFO) */
344 return(f && f->filp_vno && S_ISFIFO(f->filp_vno->v_mode));
347 /*===========================================================================*
348 * is_char_device *
349 *===========================================================================*/
350 static int is_char_device(struct filp *f)
352 /* See if this filp is a handle on a character device. This function MUST NOT
353 * block its calling thread. The given filp may or may not be locked.
356 return (f && f->filp_vno && S_ISCHR(f->filp_vno->v_mode));
359 /*===========================================================================*
360 * select_request_char *
361 *===========================================================================*/
362 static int select_request_char(struct filp *f, int *ops, int block,
363 struct fproc *rfp)
365 /* Check readiness status on a character device. Unless suitable results are
366 * available right now, this will only initiate the polling process, causing
367 * result processing to be deferred. This function MUST NOT block its calling
368 * thread. The given filp may or may not be locked.
370 dev_t dev;
371 int r, rops;
372 struct dmap *dp;
374 /* Start by remapping the device node number to a "real" device number. Those
375 * two are different only for CTTY_MAJOR aka /dev/tty, but that one single
376 * exception requires quite some extra effort here: the select code matches
377 * character driver replies to their requests based on the device number, so
378 * it needs to be aware that device numbers may be mapped. The idea is to
379 * perform the mapping once and store the result in the filp object, so that
380 * at least we don't run into problems when a process loses its controlling
381 * terminal while doing a select (see also free_proc). It should be noted
382 * that it is possible that multiple processes share the same /dev/tty filp,
383 * and they may not all have a controlling terminal. The ctty-less processes
384 * should never pass the mapping; a more problematic case is checked below.
386 * The cdev_map call also checks the major number for rough validity, so that
387 * we can use it to index the dmap array safely a bit later.
389 if ((dev = cdev_map(f->filp_vno->v_sdev, rfp)) == NO_DEV)
390 return(ENXIO);
392 if (f->filp_char_select_dev != NO_DEV && f->filp_char_select_dev != dev) {
393 /* Currently, this case can occur as follows: a process with a
394 * controlling terminal opens /dev/tty and forks, the new child starts
395 * a new session, opens a new controlling terminal, and both parent and
396 * child call select on the /dev/tty file descriptor. If this case ever
397 * becomes real, a better solution may be to force-close a filp for
398 * /dev/tty when a new controlling terminal is opened.
400 printf("VFS: file pointer has multiple controlling TTYs!\n");
401 return(EIO);
403 f->filp_char_select_dev = dev; /* set before possibly suspending */
405 rops = *ops;
407 /* By default, nothing to do */
408 *ops = 0;
410 if (!block && (f->filp_select_flags & FSF_BLOCKED)) {
411 /* This filp is blocked waiting for a reply, but we don't want to
412 * block ourselves. Unless we're awaiting the initial reply, these
413 * operations won't be ready */
414 if (!(f->filp_select_flags & FSF_BUSY)) {
415 if ((rops & SEL_RD) && (f->filp_select_flags & FSF_RD_BLOCK))
416 rops &= ~SEL_RD;
417 if ((rops & SEL_WR) && (f->filp_select_flags & FSF_WR_BLOCK))
418 rops &= ~SEL_WR;
419 if ((rops & SEL_ERR) && (f->filp_select_flags & FSF_ERR_BLOCK))
420 rops &= ~SEL_ERR;
421 if (!(rops & (SEL_RD|SEL_WR|SEL_ERR)))
422 return(OK);
426 f->filp_select_flags |= FSF_UPDATE;
427 if (block) {
428 rops |= SEL_NOTIFY;
429 if (rops & SEL_RD) f->filp_select_flags |= FSF_RD_BLOCK;
430 if (rops & SEL_WR) f->filp_select_flags |= FSF_WR_BLOCK;
431 if (rops & SEL_ERR) f->filp_select_flags |= FSF_ERR_BLOCK;
434 if (f->filp_select_flags & FSF_BUSY)
435 return(SUSPEND);
437 dp = &dmap[major(dev)];
438 if (dp->dmap_sel_busy)
439 return(SUSPEND);
441 f->filp_select_flags &= ~FSF_UPDATE;
442 r = cdev_select(dev, rops);
443 if (r != OK)
444 return(r);
446 dp->dmap_sel_busy = TRUE;
447 dp->dmap_sel_filp = f;
448 f->filp_select_flags |= FSF_BUSY;
450 return(SUSPEND);
453 /*===========================================================================*
454 * select_request_file *
455 *===========================================================================*/
456 static int select_request_file(struct filp *UNUSED(f), int *UNUSED(ops),
457 int UNUSED(block), struct fproc *UNUSED(rfp))
459 /* Files are always ready, so output *ops is input *ops */
460 return(OK);
463 /*===========================================================================*
464 * select_request_pipe *
465 *===========================================================================*/
466 static int select_request_pipe(struct filp *f, int *ops, int block,
467 struct fproc *UNUSED(rfp))
469 /* Check readiness status on a pipe. The given filp is locked. This function
470 * may block its calling thread if necessary.
472 int orig_ops, r = 0, err;
474 orig_ops = *ops;
476 if ((*ops & (SEL_RD|SEL_ERR))) {
477 /* Check if we can read 1 byte */
478 err = pipe_check(f, READING, f->filp_flags & ~O_NONBLOCK, 1,
479 1 /* Check only */);
481 if (err != SUSPEND)
482 r |= SEL_RD;
483 if (err < 0 && err != SUSPEND)
484 r |= SEL_ERR;
487 if ((*ops & (SEL_WR|SEL_ERR))) {
488 /* Check if we can write 1 byte */
489 err = pipe_check(f, WRITING, f->filp_flags & ~O_NONBLOCK, 1,
490 1 /* Check only */);
492 if (err != SUSPEND)
493 r |= SEL_WR;
494 if (err < 0 && err != SUSPEND)
495 r |= SEL_ERR;
498 /* Some options we collected might not be requested. */
499 *ops = r & orig_ops;
501 if (!*ops && block)
502 f->filp_pipe_select_ops |= orig_ops;
504 return(OK);
507 /*===========================================================================*
508 * tab2ops *
509 *===========================================================================*/
510 static int tab2ops(int fd, struct selectentry *e)
512 int ops = 0;
513 if (FD_ISSET(fd, &e->readfds)) ops |= SEL_RD;
514 if (FD_ISSET(fd, &e->writefds)) ops |= SEL_WR;
515 if (FD_ISSET(fd, &e->errorfds)) ops |= SEL_ERR;
517 return(ops);
521 /*===========================================================================*
522 * ops2tab *
523 *===========================================================================*/
524 static void ops2tab(int ops, int fd, struct selectentry *e)
526 if ((ops & SEL_RD) && e->vir_readfds && FD_ISSET(fd, &e->readfds) &&
527 !FD_ISSET(fd, &e->ready_readfds)) {
528 FD_SET(fd, &e->ready_readfds);
529 e->nreadyfds++;
532 if ((ops & SEL_WR) && e->vir_writefds && FD_ISSET(fd, &e->writefds) &&
533 !FD_ISSET(fd, &e->ready_writefds)) {
534 FD_SET(fd, &e->ready_writefds);
535 e->nreadyfds++;
538 if ((ops & SEL_ERR) && e->vir_errorfds && FD_ISSET(fd, &e->errorfds) &&
539 !FD_ISSET(fd, &e->ready_errorfds)) {
540 FD_SET(fd, &e->ready_errorfds);
541 e->nreadyfds++;
546 /*===========================================================================*
547 * copy_fdsets *
548 *===========================================================================*/
549 static int copy_fdsets(struct selectentry *se, int nfds, int direction)
551 /* Copy FD sets from or to the user process calling select(2). This function
552 * MUST NOT block the calling thread.
554 int r;
555 size_t fd_setsize;
556 endpoint_t src_e, dst_e;
557 fd_set *src_fds, *dst_fds;
559 if (nfds < 0 || nfds > OPEN_MAX)
560 panic("select copy_fdsets: nfds wrong: %d", nfds);
562 /* Only copy back as many bits as the user expects. */
563 fd_setsize = (size_t) (howmany(nfds, __NFDBITS) * sizeof(__fd_mask));
565 /* Set source and destination endpoints */
566 src_e = (direction == FROM_PROC) ? se->req_endpt : SELF;
567 dst_e = (direction == FROM_PROC) ? SELF : se->req_endpt;
569 /* read set */
570 src_fds = (direction == FROM_PROC) ? se->vir_readfds : &se->ready_readfds;
571 dst_fds = (direction == FROM_PROC) ? &se->readfds : se->vir_readfds;
572 if (se->vir_readfds) {
573 r = sys_datacopy_wrapper(src_e, (vir_bytes) src_fds, dst_e,
574 (vir_bytes) dst_fds, fd_setsize);
575 if (r != OK) return(r);
578 /* write set */
579 src_fds = (direction == FROM_PROC) ? se->vir_writefds : &se->ready_writefds;
580 dst_fds = (direction == FROM_PROC) ? &se->writefds : se->vir_writefds;
581 if (se->vir_writefds) {
582 r = sys_datacopy_wrapper(src_e, (vir_bytes) src_fds, dst_e,
583 (vir_bytes) dst_fds, fd_setsize);
584 if (r != OK) return(r);
587 /* error set */
588 src_fds = (direction == FROM_PROC) ? se->vir_errorfds : &se->ready_errorfds;
589 dst_fds = (direction == FROM_PROC) ? &se->errorfds : se->vir_errorfds;
590 if (se->vir_errorfds) {
591 r = sys_datacopy_wrapper(src_e, (vir_bytes) src_fds, dst_e,
592 (vir_bytes) dst_fds, fd_setsize);
593 if (r != OK) return(r);
596 return(OK);
600 /*===========================================================================*
601 * select_cancel_all *
602 *===========================================================================*/
603 static void select_cancel_all(struct selectentry *se)
605 /* Cancel select, possibly on success. Decrease select usage and cancel timer.
606 * This function MUST NOT block its calling thread.
609 int fd;
610 struct filp *f;
612 for (fd = 0; fd < se->nfds; fd++) {
613 if ((f = se->filps[fd]) == NULL) continue;
614 se->filps[fd] = NULL;
615 select_cancel_filp(f);
618 if (se->expiry > 0) {
619 cancel_timer(&se->timer);
620 se->expiry = 0;
623 se->requestor = NULL;
626 /*===========================================================================*
627 * select_cancel_filp *
628 *===========================================================================*/
629 static void select_cancel_filp(struct filp *f)
631 /* Reduce the number of select users of this filp. This function MUST NOT block
632 * its calling thread.
634 devmajor_t major;
636 assert(f);
637 assert(f->filp_selectors > 0);
638 assert(f->filp_count > 0);
640 f->filp_selectors--;
641 if (f->filp_selectors == 0) {
642 /* No one selecting on this filp anymore, forget about select state */
643 f->filp_select_ops = 0;
644 f->filp_select_flags = 0;
645 f->filp_pipe_select_ops = 0;
647 /* If this filp is the subject of an ongoing select query to a
648 * character device, mark the query as stale, so that this filp will
649 * not be checked when the result arrives. The filp select device may
650 * still be NO_DEV if do_select fails on the initial fd check.
652 if (is_char_device(f) && f->filp_char_select_dev != NO_DEV) {
653 major = major(f->filp_char_select_dev);
654 if (dmap[major].dmap_sel_busy &&
655 dmap[major].dmap_sel_filp == f)
656 dmap[major].dmap_sel_filp = NULL; /* leave _busy set */
657 f->filp_char_select_dev = NO_DEV;
662 /*===========================================================================*
663 * select_return *
664 *===========================================================================*/
665 static void select_return(struct selectentry *se)
667 /* Return the results of a select call to the user process and revive the
668 * process. This function MUST NOT block its calling thread.
670 int r;
672 assert(!is_deferred(se)); /* Not done yet, first wait for async reply */
674 select_cancel_all(se);
676 if (se->error != OK)
677 r = se->error;
678 else
679 r = copy_fdsets(se, se->nfds, TO_PROC);
680 if (r == OK)
681 r = se->nreadyfds;
683 revive(se->req_endpt, r);
687 /*===========================================================================*
688 * select_callback *
689 *===========================================================================*/
690 void select_callback(struct filp *f, int status)
692 /* The status of a filp has changed, with the given ready operations or error.
693 * This function is currently called only for pipes, and holds the lock to
694 * the filp.
697 filp_status(f, status);
700 /*===========================================================================*
701 * init_select *
702 *===========================================================================*/
703 void init_select(void)
705 int s;
707 for (s = 0; s < MAXSELECTS; s++)
708 init_timer(&selecttab[s].timer);
712 /*===========================================================================*
713 * select_forget *
714 *===========================================================================*/
715 void select_forget(void)
717 /* The calling thread's associated process is expected to be unpaused, due to
718 * a signal that is supposed to interrupt the current system call. Totally
719 * forget about the select(). This function may block its calling thread if
720 * necessary (but it doesn't).
722 int slot;
723 struct selectentry *se;
725 for (slot = 0; slot < MAXSELECTS; slot++) {
726 se = &selecttab[slot];
727 if (se->requestor == fp)
728 break;
731 if (slot >= MAXSELECTS) return; /* Entry not found */
733 assert(se->starting == FALSE);
735 /* Do NOT test on is_deferred here. We can safely cancel ongoing queries. */
736 select_cancel_all(se);
740 /*===========================================================================*
741 * select_timeout_check *
742 *===========================================================================*/
743 void select_timeout_check(minix_timer_t *timer)
745 /* An alarm has gone off for one of the select queries. This function MUST NOT
746 * block its calling thread.
748 int s;
749 struct selectentry *se;
751 s = tmr_arg(timer)->ta_int;
752 if (s < 0 || s >= MAXSELECTS) return; /* Entry does not exist */
754 se = &selecttab[s];
755 if (se->requestor == NULL) return;
756 if (se->expiry <= 0) return; /* Strange, did we even ask for a timeout? */
757 se->expiry = 0;
758 if (is_deferred(se)) return; /* Wait for initial replies to CDEV_SELECT */
759 select_return(se);
763 /*===========================================================================*
764 * select_unsuspend_by_endpt *
765 *===========================================================================*/
766 void select_unsuspend_by_endpt(endpoint_t proc_e)
768 /* Revive blocked processes when a driver has disappeared */
769 devmajor_t major;
770 int fd, s;
771 struct selectentry *se;
772 struct filp *f;
774 for (s = 0; s < MAXSELECTS; s++) {
775 int wakehim = 0;
776 se = &selecttab[s];
777 if (se->requestor == NULL) continue;
778 if (se->requestor->fp_endpoint == proc_e) {
779 assert(se->requestor->fp_flags & FP_EXITING);
780 select_cancel_all(se);
781 continue;
784 for (fd = 0; fd < se->nfds; fd++) {
785 if ((f = se->filps[fd]) == NULL || !is_char_device(f))
786 continue;
788 assert(f->filp_char_select_dev != NO_DEV);
789 major = major(f->filp_char_select_dev);
790 if (dmap_driver_match(proc_e, major)) {
791 se->filps[fd] = NULL;
792 se->error = EIO;
793 select_cancel_filp(f);
794 wakehim = 1;
798 if (wakehim && !is_deferred(se))
799 select_return(se);
803 /*===========================================================================*
804 * select_reply1 *
805 *===========================================================================*/
806 void select_reply1(endpoint_t driver_e, devminor_t minor, int status)
808 /* Handle the initial reply to CDEV_SELECT request. This function MUST NOT
809 * block its calling thread.
811 devmajor_t major;
812 dev_t dev;
813 struct filp *f;
814 struct dmap *dp;
816 /* Figure out which device is replying */
817 if ((dp = get_dmap(driver_e)) == NULL) return;
819 major = dp-dmap;
820 dev = makedev(major, minor);
822 /* Get filp belonging to character special file */
823 if (!dp->dmap_sel_busy) {
824 printf("VFS (%s:%d): major %d was not expecting a CDEV_SELECT reply\n",
825 __FILE__, __LINE__, major);
826 return;
829 /* The select filp may have been set to NULL if the requestor has been
830 * unpaused in the meantime. In that case, we ignore the result, but we do
831 * look for other filps to restart later.
833 if ((f = dp->dmap_sel_filp) != NULL) {
834 /* Find vnode and check we got a reply from the device we expected */
835 assert(is_char_device(f));
836 assert(f->filp_char_select_dev != NO_DEV);
837 if (f->filp_char_select_dev != dev) {
838 /* This should never happen. The driver may be misbehaving.
839 * For now we assume that the reply we want will arrive later..
841 printf("VFS (%s:%d): expected reply from dev %llx not %llx\n",
842 __FILE__, __LINE__, f->filp_char_select_dev, dev);
843 return;
847 /* No longer waiting for a reply from this device */
848 dp->dmap_sel_busy = FALSE;
849 dp->dmap_sel_filp = NULL;
851 /* Process the select result only if the filp is valid. */
852 if (f != NULL) {
853 assert(f->filp_count >= 1);
854 assert(f->filp_select_flags & FSF_BUSY);
856 f->filp_select_flags &= ~FSF_BUSY;
858 /* The select call is done now, except when
859 * - another process started a select on the same filp with possibly a
860 * different set of operations.
861 * - a process does a select on the same filp but using different file
862 * descriptors.
863 * - the select has a timeout. Upon receiving this reply the operations
864 * might not be ready yet, so we want to wait for that to ultimately
865 * happen.
866 * Therefore we need to keep remembering what the operations are.
868 if (!(f->filp_select_flags & (FSF_UPDATE|FSF_BLOCKED)))
869 f->filp_select_ops = 0; /* done selecting */
870 else if (status > 0 && !(f->filp_select_flags & FSF_UPDATE))
871 /* there may be operations pending */
872 f->filp_select_ops &= ~status;
874 /* Record new filp status */
875 if (!(status == 0 && (f->filp_select_flags & FSF_BLOCKED))) {
876 if (status > 0) { /* operations ready */
877 if (status & SEL_RD)
878 f->filp_select_flags &= ~FSF_RD_BLOCK;
879 if (status & SEL_WR)
880 f->filp_select_flags &= ~FSF_WR_BLOCK;
881 if (status & SEL_ERR)
882 f->filp_select_flags &= ~FSF_ERR_BLOCK;
883 } else if (status < 0) { /* error */
884 /* Always unblock upon error */
885 f->filp_select_flags &= ~FSF_BLOCKED;
889 filp_status(f, status); /* Tell filp owners about the results */
892 select_restart_filps();
896 /*===========================================================================*
897 * select_reply2 *
898 *===========================================================================*/
899 void select_reply2(endpoint_t driver_e, devminor_t minor, int status)
901 /* Handle secondary reply to DEV_SELECT request. A secondary reply occurs when
902 * the select request is 'blocking' until an operation becomes ready. This
903 * function MUST NOT block its calling thread.
905 int slot, found, fd;
906 devmajor_t major;
907 dev_t dev;
908 struct filp *f;
909 struct dmap *dp;
910 struct selectentry *se;
912 if (status == 0) {
913 printf("VFS (%s:%d): weird status (%d) to report\n",
914 __FILE__, __LINE__, status);
915 return;
918 /* Figure out which device is replying */
919 if ((dp = get_dmap(driver_e)) == NULL) {
920 printf("VFS (%s:%d): endpoint %d is not a known driver endpoint\n",
921 __FILE__, __LINE__, driver_e);
922 return;
924 major = dp-dmap;
925 dev = makedev(major, minor);
927 /* Find all file descriptors selecting for this device */
928 for (slot = 0; slot < MAXSELECTS; slot++) {
929 se = &selecttab[slot];
930 if (se->requestor == NULL) continue; /* empty slot */
932 found = FALSE;
933 for (fd = 0; fd < se->nfds; fd++) {
934 if ((f = se->filps[fd]) == NULL) continue;
935 if (!is_char_device(f)) continue;
936 assert(f->filp_char_select_dev != NO_DEV);
937 if (f->filp_char_select_dev != dev) continue;
939 if (status > 0) { /* Operations ready */
940 /* Clear the replied bits from the request
941 * mask unless FSF_UPDATE is set.
943 if (!(f->filp_select_flags & FSF_UPDATE))
944 f->filp_select_ops &= ~status;
945 if (status & SEL_RD)
946 f->filp_select_flags &= ~FSF_RD_BLOCK;
947 if (status & SEL_WR)
948 f->filp_select_flags &= ~FSF_WR_BLOCK;
949 if (status & SEL_ERR)
950 f->filp_select_flags &= ~FSF_ERR_BLOCK;
952 ops2tab(status, fd, se);
953 } else {
954 f->filp_select_flags &= ~FSF_BLOCKED;
955 se->error = status;
957 found = TRUE;
959 /* Even if 'found' is set now, nothing may have changed for this call,
960 * as it may not have been interested in the operations that were
961 * reported as ready. Let restart_proc check.
963 if (found)
964 restart_proc(se);
967 select_restart_filps();
970 /*===========================================================================*
971 * select_restart_filps *
972 *===========================================================================*/
973 static void select_restart_filps(void)
975 /* We got a result from a character driver, and now we need to check if we can
976 * restart deferred polling operations. This function MUST NOT block its
977 * calling thread.
979 int fd, slot;
980 struct filp *f;
981 struct selectentry *se;
983 /* Locate filps that can be restarted */
984 for (slot = 0; slot < MAXSELECTS; slot++) {
985 se = &selecttab[slot];
986 if (se->requestor == NULL) continue; /* empty slot */
988 /* Only 'deferred' processes are eligible to restart */
989 if (!is_deferred(se)) continue;
991 /* Find filps that are not waiting for a reply, but have an updated
992 * status (i.e., another select on the same filp with possibly a
993 * different set of operations is to be done), and thus requires the
994 * select request to be sent again).
996 for (fd = 0; fd < se->nfds; fd++) {
997 int r, wantops, ops;
998 if ((f = se->filps[fd]) == NULL) continue;
999 if (f->filp_select_flags & FSF_BUSY) /* Still waiting for */
1000 continue; /* initial reply */
1001 if (!(f->filp_select_flags & FSF_UPDATE)) /* Must be in */
1002 continue; /* 'update' state */
1004 /* This function is suitable only for character devices. In
1005 * particular, checking pipes the same way would introduce a
1006 * serious locking problem.
1008 assert(is_char_device(f));
1010 wantops = ops = f->filp_select_ops;
1011 r = select_request_char(f, &wantops, se->block, se->requestor);
1012 if (r != OK && r != SUSPEND) {
1013 se->error = r;
1014 restart_proc(se);
1015 break; /* Error or bogus return code; abort */
1017 if (wantops & ops) ops2tab(wantops, fd, se);
1022 /*===========================================================================*
1023 * filp_status *
1024 *===========================================================================*/
1025 static void filp_status(f, status)
1026 struct filp *f;
1027 int status;
1029 /* Tell processes that need to know about the status of this filp. This
1030 * function MUST NOT block its calling thread.
1032 int fd, slot, found;
1033 struct selectentry *se;
1035 for (slot = 0; slot < MAXSELECTS; slot++) {
1036 se = &selecttab[slot];
1037 if (se->requestor == NULL) continue; /* empty slot */
1039 found = FALSE;
1040 for (fd = 0; fd < se->nfds; fd++) {
1041 if (se->filps[fd] != f) continue;
1042 if (status < 0)
1043 se->error = status;
1044 else
1045 ops2tab(status, fd, se);
1046 found = TRUE;
1048 if (found)
1049 restart_proc(se);
1053 /*===========================================================================*
1054 * restart_proc *
1055 *===========================================================================*/
1056 static void restart_proc(se)
1057 struct selectentry *se;
1059 /* Tell process about select results (if any) unless there are still results
1060 * pending. This function MUST NOT block its calling thread.
1063 if ((se->nreadyfds > 0 || se->error != OK || !se->block) && !is_deferred(se))
1064 select_return(se);
1067 /*===========================================================================*
1068 * wipe_select *
1069 *===========================================================================*/
1070 static void wipe_select(struct selectentry *se)
1072 se->nfds = 0;
1073 se->nreadyfds = 0;
1074 se->error = OK;
1075 se->block = 0;
1076 memset(se->filps, 0, sizeof(se->filps));
1078 FD_ZERO(&se->readfds);
1079 FD_ZERO(&se->writefds);
1080 FD_ZERO(&se->errorfds);
1081 FD_ZERO(&se->ready_readfds);
1082 FD_ZERO(&se->ready_writefds);
1083 FD_ZERO(&se->ready_errorfds);
1086 /*===========================================================================*
1087 * select_lock_filp *
1088 *===========================================================================*/
1089 static void select_lock_filp(struct filp *f, int ops)
1091 /* Lock a filp and vnode based on which operations are requested. This function
1092 * may block its calling thread, obviously.
1094 tll_access_t locktype;
1096 locktype = VNODE_READ; /* By default */
1098 if (ops & (SEL_WR|SEL_ERR))
1099 /* Selecting for error or writing requires exclusive access */
1100 locktype = VNODE_WRITE;
1102 lock_filp(f, locktype);