Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc/rpc PR/50408: Pedro Giffuni: Provide a way for rpc ...



details:   https://anonhg.NetBSD.org/src/rev/31797d482b68
branches:  trunk
changeset: 811620:31797d482b68
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Nov 07 23:09:20 2015 +0000

description:
PR/50408: Pedro Giffuni: Provide a way for rpc to use poll(2) instead of
select(2), and the linux svc_pollfd and svc_maxpollfd members. Our select(2)
implementation does not suffer from the FD_SETSIZE limitation so this is
not turned on by default.

diffstat:

 lib/libc/rpc/rpc_internal.h |    3 +-
 lib/libc/rpc/svc_fdset.c    |  142 ++++++++++++++++++++++++++++++++++++++++++-
 lib/libc/rpc/svc_run.c      |  112 ++++++++++++++++++++++++++++-----
 lib/libc/rpc/svc_vc.c       |   13 +--
 4 files changed, 237 insertions(+), 33 deletions(-)

diffs (truncated from 453 to 300 lines):

diff -r f46fca815ac5 -r 31797d482b68 lib/libc/rpc/rpc_internal.h
--- a/lib/libc/rpc/rpc_internal.h       Sat Nov 07 21:07:18 2015 +0000
+++ b/lib/libc/rpc/rpc_internal.h       Sat Nov 07 23:09:20 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rpc_internal.h,v 1.7 2013/05/07 21:08:45 christos Exp $        */
+/*     $NetBSD: rpc_internal.h,v 1.8 2015/11/07 23:09:20 christos Exp $        */
 
 /*-
  * Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -63,5 +63,6 @@
 
 extern SVCXPRT **__svc_xports;
 extern int __svc_maxrec;
+extern int __svc_flags;
 
 int __clnt_sigfillset(sigset_t *);
diff -r f46fca815ac5 -r 31797d482b68 lib/libc/rpc/svc_fdset.c
--- a/lib/libc/rpc/svc_fdset.c  Sat Nov 07 21:07:18 2015 +0000
+++ b/lib/libc/rpc/svc_fdset.c  Sat Nov 07 23:09:20 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: svc_fdset.c,v 1.8 2015/11/07 20:24:00 christos Exp $   */
+/*     $NetBSD: svc_fdset.c,v 1.9 2015/11/07 23:09:20 christos Exp $   */
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: svc_fdset.c,v 1.8 2015/11/07 20:24:00 christos Exp $");
+__RCSID("$NetBSD: svc_fdset.c,v 1.9 2015/11/07 23:09:20 christos Exp $");
 
 
 #include "reentrant.h"
@@ -47,6 +47,7 @@
 #endif
 #include <stdlib.h>
 #include <string.h>
+#include <poll.h>
 
 #include "svc_fdset.h"
 
@@ -54,11 +55,17 @@
 #undef svc_maxfd
 extern __fd_set_256 svc_fdset;
 extern int svc_maxfd;
+int __svc_flags;
 
 struct svc_fdset {
+       /* select */
        fd_set *fdset;
        int     fdmax;
        int     fdsize;
+       /* poll */
+       struct pollfd *fdp;
+       int     fdnum;
+       int     fdused;
 };
 
 /* The single threaded, one global fd_set version */
@@ -138,10 +145,85 @@
        struct svc_fdset *fds = v;
        DPRINTF_FDSET(fds, "free");
 
+       free(fds->fdp);
        free(fds->fdset);
        free(fds);
 }
 
+static void
+svc_pollfd_init(struct pollfd *pfd, int nfd)
+{
+       for (int i = 0; i < nfd; i++) {
+               pfd[i].fd = -1;
+               pfd[i].events = POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND;
+       }
+}
+
+static struct pollfd *
+svc_pollfd_alloc(struct svc_fdset *fds)
+{
+       fds->fdnum = FD_SETSIZE;
+       fds->fdp = calloc(fds->fdnum, sizeof(*fds->fdp));
+       if (fds->fdp == NULL)
+               return NULL;
+       svc_pollfd_init(fds->fdp, fds->fdnum);
+       return fds->fdp;
+}
+
+
+static struct svc_fdset *
+svc_pollfd_add(int fd, struct svc_fdset *fds)
+{
+       struct pollfd *pfd;
+
+       if ((pfd = svc_pollfd_alloc(fds)) == NULL)
+               return NULL;
+
+       for (int i = 0; i < fds->fdnum; i++)
+               if (pfd[i].fd == -1) {
+                       if (i > fds->fdused)
+                               fds->fdused = i + 1;
+                       pfd[i].fd = fd;
+                       return fds;
+               }
+
+       pfd = realloc(fds->fdp, (fds->fdnum + FD_SETSIZE) * sizeof(*fds->fdp));
+       if (pfd == NULL)
+               return NULL;
+
+       svc_pollfd_init(pfd + fds->fdnum, FD_SETSIZE);
+       pfd[fds->fdnum].fd = fd;
+       fds->fdused = fds->fdnum + 1;
+       fds->fdnum += FD_SETSIZE;
+       return fds;
+}
+
+static struct svc_fdset *
+svc_pollfd_del(int fd, struct svc_fdset *fds)
+{
+       struct pollfd *pfd;
+
+       if ((pfd = svc_pollfd_alloc(fds)) == NULL)
+               return NULL;
+
+       for (int i = 0; i < fds->fdnum; i++) {
+               if (pfd[i].fd != fd)
+                       continue;
+
+               pfd[i].fd = -1;
+               if (i != fds->fdused - 1)
+                       return fds;
+
+               do
+                       if (pfd[i].fd != -1) 
+                               break;
+               while (--i >= 0);
+               fds->fdused = i + 1;
+               return fds;
+       }
+       return NULL;
+}
+
 static struct svc_fdset *
 svc_fdset_resize(int fd, struct svc_fdset *fds)
 {
@@ -206,6 +288,7 @@
 svc_fdset_init(int flags)
 {
        DPRINTF("%x", flags);
+       __svc_flags = flags;
        if ((flags & SVC_FDSET_MT) && fdsetkey == -2)
                fdsetkey = -1;
 }
@@ -214,9 +297,14 @@
 svc_fdset_zero(void)
 {
        DPRINTF("zero");
+
        struct svc_fdset *fds = svc_fdset_alloc(0);
        memset(fds->fdset, 0, fds->fdsize);
        fds->fdmax = -1;
+
+       free(fds->fdp);
+       fds->fdp = NULL;
+       fds->fdnum = fds->fdused = 0;
 }
 
 int
@@ -234,7 +322,7 @@
        DPRINTF_FDSET(fds, "%d", fd);
 
        svc_fdset_sanitize(fds);
-       return 0;
+       return svc_pollfd_add(fd, fds) ? 0 : -1;
 }
 
 int
@@ -262,7 +350,7 @@
        DPRINTF_FDSET(fds, "%d", fd);
 
        svc_fdset_sanitize(fds);
-       return 0;
+       return svc_pollfd_del(fd, fds) ? 0 : -1;
 }
 
 fd_set *
@@ -314,3 +402,49 @@
        DPRINTF_FDSET(fds, "getsize");
        return fds->fdsize;
 }
+
+struct pollfd *
+svc_pollfd_copy(const struct pollfd *orig)
+{
+       int size = svc_fdset_getsize(0);
+       struct pollfd *copy = calloc(size, sizeof(*orig));
+       if (copy == NULL)
+               return NULL;
+       if (orig)
+               memcpy(copy, orig, size * sizeof(*orig));
+       return copy;
+}
+
+struct pollfd *
+svc_pollfd_get(void)
+{
+       struct svc_fdset *fds = svc_fdset_alloc(0);
+
+       if (fds == NULL)
+               return NULL;
+
+       DPRINTF_FDSET(fds, "getpoll");
+       return fds->fdp;
+}
+
+int *
+svc_pollfd_getmax(void)
+{
+       struct svc_fdset *fds = svc_fdset_alloc(0);
+
+       if (fds == NULL)
+               return NULL;
+       return &fds->fdused;
+}
+
+int
+svc_pollfd_getsize(int fd)
+{
+       struct svc_fdset *fds = svc_fdset_alloc(fd);
+
+       if (fds == NULL)
+               return -1;
+
+       DPRINTF_FDSET(fds, "getsize");
+       return fds->fdnum;
+}
diff -r f46fca815ac5 -r 31797d482b68 lib/libc/rpc/svc_run.c
--- a/lib/libc/rpc/svc_run.c    Sat Nov 07 21:07:18 2015 +0000
+++ b/lib/libc/rpc/svc_run.c    Sat Nov 07 23:09:20 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: svc_run.c,v 1.24 2015/11/07 17:34:33 christos Exp $    */
+/*     $NetBSD: svc_run.c,v 1.25 2015/11/07 23:09:20 christos Exp $    */
 
 /*
  * Copyright (c) 2010, Oracle America, Inc.
@@ -37,7 +37,7 @@
 static char *sccsid = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";
 static char *sccsid = "@(#)svc_run.c   2.1 88/07/29 4.0 RPCSRC";
 #else
-__RCSID("$NetBSD: svc_run.c,v 1.24 2015/11/07 17:34:33 christos Exp $");
+__RCSID("$NetBSD: svc_run.c,v 1.25 2015/11/07 23:09:20 christos Exp $");
 #endif
 #endif
 
@@ -53,6 +53,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <poll.h>
 
 #include <rpc/rpc.h>
 
@@ -64,10 +65,10 @@
 __weak_alias(svc_exit,_svc_exit)
 #endif
 
-void
-svc_run(void)
+static void
+svc_run_select(void)
 {
-       fd_set *readfds, *cleanfds;
+       fd_set *readfds;
        struct timeval timeout;
        int *maxfd, fdsize;
 #ifndef RUMP_RPC               
@@ -78,26 +79,32 @@
 #endif
 
        readfds = NULL;
-       cleanfds = NULL;
        fdsize = 0;
        timeout.tv_sec = 30;
        timeout.tv_usec = 0;
 
        for (;;) {
                rwlock_rdlock(&svc_fd_lock);
+
+               maxfd = svc_fdset_getmax();
+               if (maxfd == NULL) {
+                       warn("%s: can't get maxfd", __func__);
+                       goto out;
+               }
+
                if (fdsize != svc_fdset_getsize(0)) {
                        fdsize = svc_fdset_getsize(0);
                        free(readfds);
                        readfds = svc_fdset_copy(svc_fdset_get());
-                       free(cleanfds);



Home | Main Index | Thread Index | Old Index