[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] mini-os: implement poll(2)
Wei Liu, le Tue 19 Feb 2013 18:36:16 +0000, a écrit : > V4 of the patch > > In this version I try to mimic Linux's do_poll behavior. The pollfd > array is always scanned, even if some fds in the middle of the loops are > invalid. In this case we need to do no-blocking select regardless of > timeout, because we already receive events. > > I tried to document the behavior as much as possible, please see > comments in code. > > > Wei. > > ----8<--- > From 39789af96d9e5a6d4f3d8a9e86546b62918c30df Mon Sep 17 00:00:00 2001 > From: Wei Liu <wei.liu2@xxxxxxxxxx> > Date: Tue, 19 Feb 2013 12:15:03 +0000 > Subject: [PATCH] mini-os: implement poll(2) > > It is just a wrapper around select(2). > > Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> Acked-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx> > --- > extras/mini-os/include/posix/poll.h | 1 + > extras/mini-os/lib/sys.c | 117 > ++++++++++++++++++++++++++++++++++- > 2 files changed, 117 insertions(+), 1 deletion(-) > create mode 100644 extras/mini-os/include/posix/poll.h > > diff --git a/extras/mini-os/include/posix/poll.h > b/extras/mini-os/include/posix/poll.h > new file mode 100644 > index 0000000..06fb41a > --- /dev/null > +++ b/extras/mini-os/include/posix/poll.h > @@ -0,0 +1 @@ > +#include <sys/poll.h> > diff --git a/extras/mini-os/lib/sys.c b/extras/mini-os/lib/sys.c > index 3cc3340..10a04eb 100644 > --- a/extras/mini-os/lib/sys.c > +++ b/extras/mini-os/lib/sys.c > @@ -31,6 +31,7 @@ > #include <tpm_tis.h> > #include <xenbus.h> > #include <xenstore.h> > +#include <poll.h> > > #include <sys/types.h> > #include <sys/unistd.h> > @@ -678,6 +679,29 @@ static void dump_set(int nfds, fd_set *readfds, fd_set > *writefds, fd_set *except > #define dump_set(nfds, readfds, writefds, exceptfds, timeout) > #endif > > +#ifdef LIBC_DEBUG > +static void dump_pollfds(struct pollfd *pfd, int nfds, int timeout) > +{ > + int i, comma, fd; > + > + printk("["); > + comma = 0; > + for (i = 0; i < nfds; i++) { > + fd = pfd[i].fd; > + if (comma) > + printk(", "); > + printk("%d(%c)/%02x", fd, file_types[files[fd].type], > + pfd[i].events); > + comma = 1; > + } > + printk("]"); > + > + printk(", %d, %d", nfds, timeout); > +} > +#else > +#define dump_pollfds(pfds, nfds, timeout) > +#endif > + > /* Just poll without blocking */ > static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set > *exceptfds) > { > @@ -983,6 +1007,98 @@ out: > return ret; > } > > +/* Wrap around select */ > +int poll(struct pollfd _pfd[], nfds_t _nfds, int _timeout) > +{ > + int n, ret; > + int i, fd; > + struct timeval _timeo, *timeo = NULL; > + fd_set rfds, wfds, efds; > + int max_fd = -1; > + > + DEBUG("poll("); > + dump_pollfds(_pfd, _nfds, _timeout); > + DEBUG(")\n"); > + > + FD_ZERO(&rfds); > + FD_ZERO(&wfds); > + FD_ZERO(&efds); > + > + n = 0; > + > + for (i = 0; i < _nfds; i++) { > + fd = _pfd[i].fd; > + _pfd[i].revents = 0; > + > + /* fd < 0, revents = 0, which is already set */ > + if (fd < 0) continue; > + > + /* fd is invalid, revents = POLLNVAL, increment counter */ > + if (fd >= NOFILE || files[fd].type == FTYPE_NONE) { > + n++; > + _pfd[i].revents |= POLLNVAL; > + continue; > + } > + > + /* normal case, map POLL* into readfds and writefds: > + * POLLIN -> readfds > + * POLLOUT -> writefds > + * POLL* -> none > + */ > + if (_pfd[i].events & POLLIN) > + FD_SET(fd, &rfds); > + if (_pfd[i].events & POLLOUT) > + FD_SET(fd, &wfds); > + /* always set exceptfds */ > + FD_SET(fd, &efds); > + if (fd > max_fd) > + max_fd = fd; > + } > + > + /* should never sleep when we already have events */ > + if (n) { > + _timeo.tv_sec = 0; > + _timeo.tv_usec = 0; > + timeo = &_timeo; > + } else if (_timeout >= 0) { > + /* normal case, construct _timeout, might sleep */ > + _timeo.tv_sec = _timeout / 1000; > + _timeo.tv_usec = (_timeout % 1000) * 1000; > + timeo = &_timeo; > + } else { > + /* _timeout < 0, block forever */ > + timeo = NULL; > + } > + > + > + ret = select(max_fd+1, &rfds, &wfds, &efds, timeo); > + /* error in select, just return, errno is set by select() */ > + if (ret < 0) > + return ret; > + > + for (i = 0; i < _nfds; i++) { > + fd = _pfd[i].fd; > + > + /* the revents has already been set for all error case */ > + if (fd < 0 || fd >= NOFILE || files[fd].type == FTYPE_NONE) > + continue; > + > + if (FD_ISSET(fd, &rfds) || FD_ISSET(fd, &wfds) || FD_ISSET(fd, > &efds)) > + n++; > + if (FD_ISSET(fd, &efds)) { > + /* anything bad happens we set POLLERR */ > + _pfd[i].revents |= POLLERR; > + continue; > + } > + if (FD_ISSET(fd, &rfds)) > + _pfd[i].revents |= POLLIN; > + if (FD_ISSET(fd, &wfds)) > + _pfd[i].revents |= POLLOUT; > + } > + > + return n; > +} > + > #ifdef HAVE_LWIP > int socket(int domain, int type, int protocol) > { > @@ -1360,7 +1476,6 @@ unsupported_function(int, tcgetattr, 0); > unsupported_function(int, grantpt, -1); > unsupported_function(int, unlockpt, -1); > unsupported_function(char *, ptsname, NULL); > -unsupported_function(int, poll, -1); > > /* net/if.h */ > unsupported_function_log(unsigned int, if_nametoindex, -1); > -- > 1.7.10.4 > > > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxx > http://lists.xen.org/xen-devel > -- Samuel <s> on se croirait en cool : Some browsers close comments on the first ">" character, so to hide script content from such browsers, you can transpose operands for relational and shift operators (e.g., use "y < x" rather than "x > y") or use scripting language-dependent escapes for ">". -+- #ens-mim -+- _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |