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