[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.