diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2003-09-23 16:51:15 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2003-09-23 16:51:15 +0000 |
commit | 6bb276a1685d8546283d224a3d249c66cc329264 (patch) | |
tree | 5e1c80d6cad38a8a82f5832e1e315103e7029eb9 /sys/kern/sys_pipe.c | |
parent | 96675671ec2520ade2f83b31563ab4da72bd443d (diff) |
Replace select backends with poll backends. selscan() and pollscan()
now call the poll backend. With this change we implement greater
poll(2) functionality instead of emulating it via the select backend.
Adapted from NetBSD and including some changes from FreeBSD.
Tested by many, deraadt@ OK
Diffstat (limited to 'sys/kern/sys_pipe.c')
-rw-r--r-- | sys/kern/sys_pipe.c | 67 |
1 files changed, 31 insertions, 36 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index ac7416eb1df..3e36d581fd4 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_pipe.c,v 1.43 2002/03/14 01:27:04 millert Exp $ */ +/* $OpenBSD: sys_pipe.c,v 1.44 2003/09/23 16:51:12 millert Exp $ */ /* * Copyright (c) 1996 John S. Dyson @@ -46,6 +46,7 @@ #include <sys/syscallargs.h> #include <sys/event.h> #include <sys/lock.h> +#include <sys/poll.h> #include <uvm/uvm_extern.h> @@ -57,13 +58,13 @@ int pipe_read(struct file *, off_t *, struct uio *, struct ucred *); int pipe_write(struct file *, off_t *, struct uio *, struct ucred *); int pipe_close(struct file *, struct proc *); -int pipe_select(struct file *, int which, struct proc *); +int pipe_poll(struct file *, int events, struct proc *); int pipe_kqfilter(struct file *fp, struct knote *kn); int pipe_ioctl(struct file *, u_long, caddr_t, struct proc *); int pipe_stat(struct file *fp, struct stat *ub, struct proc *p); static struct fileops pipeops = { - pipe_read, pipe_write, pipe_ioctl, pipe_select, pipe_kqfilter, + pipe_read, pipe_write, pipe_ioctl, pipe_poll, pipe_kqfilter, pipe_stat, pipe_close }; @@ -540,7 +541,7 @@ retrywrite: /* * We have no more space and have something to offer, - * wake up selects. + * wake up select/poll. */ pipeselwakeup(wpipe); @@ -587,8 +588,7 @@ retrywrite: if (error == 0) microtime(&wpipe->pipe_mtime); /* - * We have something to offer, - * wake up select. + * We have something to offer, wake up select/poll. */ if (wpipe->pipe_buffer.cnt) pipeselwakeup(wpipe); @@ -638,48 +638,43 @@ pipe_ioctl(fp, cmd, data, p) } int -pipe_select(fp, which, p) +pipe_poll(fp, events, p) struct file *fp; - int which; + int events; struct proc *p; { struct pipe *rpipe = (struct pipe *)fp->f_data; struct pipe *wpipe; + int revents = 0; wpipe = rpipe->pipe_peer; - switch (which) { - - case FREAD: + if (events & (POLLIN | POLLRDNORM)) { if ((rpipe->pipe_buffer.cnt > 0) || - (rpipe->pipe_state & PIPE_EOF)) { - return (1); - } - selrecord(p, &rpipe->pipe_sel); - rpipe->pipe_state |= PIPE_SEL; - break; + (rpipe->pipe_state & PIPE_EOF)) + revents |= events & (POLLIN | POLLRDNORM); + } - case FWRITE: - if ((wpipe == NULL) || - (wpipe->pipe_state & PIPE_EOF) || - ((wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) >= PIPE_BUF)) { - return (1); - } - selrecord(p, &wpipe->pipe_sel); - wpipe->pipe_state |= PIPE_SEL; - break; + /* NOTE: POLLHUP and POLLOUT/POLLWRNORM are mutually exclusive */ + if ((rpipe->pipe_state & PIPE_EOF) || + (wpipe == NULL) || + (wpipe->pipe_state & PIPE_EOF)) + revents |= POLLHUP; + else if (events & (POLLOUT | POLLWRNORM)) { + if ((wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) >= PIPE_BUF) + revents |= events & (POLLOUT | POLLWRNORM); + } - case 0: - if ((rpipe->pipe_state & PIPE_EOF) || - (wpipe == NULL) || - (wpipe->pipe_state & PIPE_EOF)) { - return (1); + if (revents == 0) { + if (events & (POLLIN | POLLRDNORM)) { + selrecord(p, &rpipe->pipe_sel); + rpipe->pipe_state |= PIPE_SEL; + } + if (events & (POLLOUT | POLLWRNORM)) { + selrecord(p, &wpipe->pipe_sel); + wpipe->pipe_state |= PIPE_SEL; } - - selrecord(p, &rpipe->pipe_sel); - rpipe->pipe_state |= PIPE_SEL; - break; } - return (0); + return (revents); } int |