Module Name: src
Committed By: christos
Date: Fri Nov 6 19:34:14 UTC 2015
Modified Files:
src/lib/libc/rpc: Makefile.inc svc.c svc_fdset.c svc_fdset.h svc_run.c
svc_vc.c
Log Message:
- Provide multi-threaded fdset's for everyone not just rump if requested.
- Abstract fd_set access, and don't limit the fd_set size.
- Maintain binary compatibility by keeping the old global variables around.
To generate a diff of this commit:
cvs rdiff -u -r1.22 -r1.23 src/lib/libc/rpc/Makefile.inc \
src/lib/libc/rpc/svc_run.c
cvs rdiff -u -r1.34 -r1.35 src/lib/libc/rpc/svc.c
cvs rdiff -u -r1.1 -r1.2 src/lib/libc/rpc/svc_fdset.c \
src/lib/libc/rpc/svc_fdset.h
cvs rdiff -u -r1.30 -r1.31 src/lib/libc/rpc/svc_vc.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libc/rpc/Makefile.inc
diff -u src/lib/libc/rpc/Makefile.inc:1.22 src/lib/libc/rpc/Makefile.inc:1.23
--- src/lib/libc/rpc/Makefile.inc:1.22 Wed Apr 15 15:13:47 2015
+++ src/lib/libc/rpc/Makefile.inc Fri Nov 6 14:34:13 2015
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.inc,v 1.22 2015/04/15 19:13:47 mrg Exp $
+# $NetBSD: Makefile.inc,v 1.23 2015/11/06 19:34:13 christos Exp $
# librpc sources
.PATH: ${.CURDIR}/rpc
@@ -12,7 +12,7 @@ SRCS+= auth_none.c auth_unix.c authunix_
pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c rpc_callmsg.c \
rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c rpcb_st_xdr.c \
svc.c svc_auth.c svc_dg.c svc_auth_unix.c svc_generic.c svc_raw.c \
- svc_run.c svc_simple.c svc_vc.c \
+ svc_run.c svc_simple.c svc_vc.c svc_fdset.c \
xdr.c xdr_array.c xdr_float.c xdr_mem.c xdr_rec.c xdr_reference.c \
xdr_stdio.c xdr_sizeof.c __rpc_getxid.c
Index: src/lib/libc/rpc/svc_run.c
diff -u src/lib/libc/rpc/svc_run.c:1.22 src/lib/libc/rpc/svc_run.c:1.23
--- src/lib/libc/rpc/svc_run.c:1.22 Mon Mar 11 16:19:29 2013
+++ src/lib/libc/rpc/svc_run.c Fri Nov 6 14:34:13 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: svc_run.c,v 1.22 2013/03/11 20:19:29 tron Exp $ */
+/* $NetBSD: svc_run.c,v 1.23 2015/11/06 19:34:13 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.22 2013/03/11 20:19:29 tron Exp $");
+__RCSID("$NetBSD: svc_run.c,v 1.23 2015/11/06 19:34:13 christos Exp $");
#endif
#endif
@@ -50,6 +50,7 @@ __RCSID("$NetBSD: svc_run.c,v 1.22 2013/
#include <err.h>
#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -66,9 +67,9 @@ __weak_alias(svc_exit,_svc_exit)
void
svc_run(void)
{
- fd_set readfds, cleanfds;
+ fd_set *readfds, *cleanfds;
struct timeval timeout;
- int maxfd;
+ int maxfd, fdsize;
#ifndef RUMP_RPC
int probs = 0;
#endif
@@ -76,16 +77,24 @@ svc_run(void)
extern rwlock_t svc_fd_lock;
#endif
+ readfds = NULL;
+ cleanfds = NULL;
+ fdsize = 0;
timeout.tv_sec = 30;
timeout.tv_usec = 0;
for (;;) {
rwlock_rdlock(&svc_fd_lock);
- readfds = *get_fdset();
- cleanfds = *get_fdset();
- maxfd = *get_fdsetmax();
+ if (fdsize != svc_fdset_getsize(0)) {
+ fdsize = svc_fdset_getsize(0);
+ free(readfds);
+ readfds = svc_fdset_copy(svc_fdset_get());
+ free(cleanfds);
+ cleanfds = svc_fdset_copy(svc_fdset_get());
+ }
+ maxfd = *svc_fdset_getmax();
rwlock_unlock(&svc_fd_lock);
- switch (select(maxfd + 1, &readfds, NULL, NULL, &timeout)) {
+ switch (select(maxfd + 1, readfds, NULL, NULL, &timeout)) {
case -1:
#ifndef RUMP_RPC
if ((errno == EINTR || errno == EBADF) && probs < 100) {
@@ -97,17 +106,20 @@ svc_run(void)
continue;
}
warn("%s: select failed", __func__);
- return;
+ goto out;
case 0:
- __svc_clean_idle(&cleanfds, 30, FALSE);
+ __svc_clean_idle(cleanfds, 30, FALSE);
continue;
default:
- svc_getreqset(&readfds);
+ svc_getreqset2(readfds, fdsize);
#ifndef RUMP_RPC
probs = 0;
#endif
}
}
+out:
+ free(readfds);
+ free(cleanfds);
}
/*
@@ -122,6 +134,6 @@ svc_exit(void)
#endif
rwlock_wrlock(&svc_fd_lock);
- FD_ZERO(get_fdset());
+ svc_fdset_zero();
rwlock_unlock(&svc_fd_lock);
}
Index: src/lib/libc/rpc/svc.c
diff -u src/lib/libc/rpc/svc.c:1.34 src/lib/libc/rpc/svc.c:1.35
--- src/lib/libc/rpc/svc.c:1.34 Mon Mar 11 16:19:29 2013
+++ src/lib/libc/rpc/svc.c Fri Nov 6 14:34:13 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: svc.c,v 1.34 2013/03/11 20:19:29 tron Exp $ */
+/* $NetBSD: svc.c,v 1.35 2015/11/06 19:34:13 christos Exp $ */
/*
* Copyright (c) 2010, Oracle America, Inc.
@@ -37,7 +37,7 @@
static char *sccsid = "@(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)svc.c 2.4 88/08/11 4.0 RPCSRC";
#else
-__RCSID("$NetBSD: svc.c,v 1.34 2013/03/11 20:19:29 tron Exp $");
+__RCSID("$NetBSD: svc.c,v 1.35 2015/11/06 19:34:13 christos Exp $");
#endif
#endif
@@ -90,7 +90,9 @@ __weak_alias(xprt_unregister,_xprt_unreg
__weak_alias(rpc_control,_rpc_control)
#endif
+/* __svc_xports[-1] is reserved for raw */
SVCXPRT **__svc_xports;
+int __svc_maxxports;
int __svc_maxrec;
#define RQCRED_SIZE 400 /* this size is excessive */
@@ -125,6 +127,40 @@ static void __xprt_do_unregister(SVCXPRT
/* *************** SVCXPRT related stuff **************** */
+static bool_t
+xprt_alloc(int sock)
+{
+ int maxset;
+ char *newxports;
+
+ if (++sock < 0)
+ return FALSE;
+
+ maxset = svc_fdset_getsize(sock);
+ if (maxset == -1)
+ return FALSE;
+
+ if (__svc_xports != NULL && maxset <= __svc_maxxports)
+ return TRUE;
+
+ if (__svc_xports != NULL)
+ --__svc_xports;
+ newxports = realloc(__svc_xports, maxset * sizeof(SVCXPRT *));
+ if (newxports == NULL) {
+ warn("%s: out of memory", __func__);
+ return FALSE;
+ }
+
+ memset(newxports + __svc_maxxports * sizeof(SVCXPRT *), 0,
+ (maxset - __svc_maxxports) * sizeof(SVCXPRT *));
+
+ __svc_xports = (void *)newxports;
+ __svc_xports++;
+ __svc_maxxports = maxset;
+
+ return TRUE;
+}
+
/*
* Activate a transport handle.
*/
@@ -135,25 +171,16 @@ xprt_register(SVCXPRT *xprt)
_DIAGASSERT(xprt != NULL);
+ rwlock_wrlock(&svc_fd_lock);
sock = xprt->xp_fd;
- rwlock_wrlock(&svc_fd_lock);
- if (__svc_xports == NULL) {
- __svc_xports = mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *));
- if (__svc_xports == NULL) {
- warn("%s: out of memory", __func__);
- goto out;
- }
- memset(__svc_xports, '\0', FD_SETSIZE * sizeof(SVCXPRT *));
- }
- if (sock >= FD_SETSIZE) {
- warnx("%s: socket descriptor %d too large for setsize %u",
- __func__, sock, (unsigned)FD_SETSIZE);
+ if (!xprt_alloc(sock))
goto out;
- }
+
__svc_xports[sock] = xprt;
- FD_SET(sock, get_fdset());
- *get_fdsetmax() = max(*get_fdsetmax(), sock);
+ if (sock != -1) {
+ svc_fdset_set(sock);
+ }
rwlock_unlock(&svc_fd_lock);
return (TRUE);
@@ -180,24 +207,30 @@ __xprt_unregister_unlocked(SVCXPRT *xprt
static void
__xprt_do_unregister(SVCXPRT *xprt, bool_t dolock)
{
- int sock;
+ int sock, *fdmax;
_DIAGASSERT(xprt != NULL);
- sock = xprt->xp_fd;
-
if (dolock)
rwlock_wrlock(&svc_fd_lock);
- if ((sock < FD_SETSIZE) && (__svc_xports[sock] == xprt)) {
- __svc_xports[sock] = NULL;
- FD_CLR(sock, get_fdset());
- if (sock >= *get_fdsetmax()) {
- for ((*get_fdsetmax())--; *get_fdsetmax() >= 0;
- (*get_fdsetmax())--)
- if (__svc_xports[*get_fdsetmax()])
- break;
- }
- }
+
+ sock = xprt->xp_fd;
+ if (sock >= __svc_maxxports || __svc_xports[sock] != xprt)
+ goto out;
+
+ __svc_xports[sock] = NULL;
+ if (sock == -1)
+ goto out;
+ fdmax = svc_fdset_getmax();
+ if (sock < *fdmax)
+ goto clr;
+
+ for ((*fdmax)--; *fdmax >= 0; (*fdmax)--)
+ if (__svc_xports[*fdmax])
+ break;
+clr:
+ svc_fdset_clr(sock);
+out:
if (dolock)
rwlock_unlock(&svc_fd_lock);
}
@@ -600,15 +633,15 @@ svcerr_progvers(SVCXPRT *xprt, rpcvers_t
void
svc_getreq(int rdfds)
{
- fd_set readfds;
+ fd_set *readfds = svc_fdset_copy(NULL);
- FD_ZERO(&readfds);
- readfds.fds_bits[0] = (unsigned int)rdfds;
- svc_getreqset(&readfds);
+ readfds->fds_bits[0] = (unsigned int)rdfds;
+ svc_getreqset(readfds);
+ free(readfds);
}
void
-svc_getreqset(fd_set *readfds)
+svc_getreqset2(fd_set *readfds, int maxsize)
{
uint32_t mask, *maskp;
int sock, bit, fd;
@@ -616,7 +649,7 @@ svc_getreqset(fd_set *readfds)
_DIAGASSERT(readfds != NULL);
maskp = readfds->fds_bits;
- for (sock = 0; sock < FD_SETSIZE; sock += NFDBITS) {
+ for (sock = 0; sock < maxsize; sock += NFDBITS) {
for (mask = *maskp++; (bit = ffs((int)mask)) != 0;
mask ^= (1 << (bit - 1))) {
/* sock has input waiting */
@@ -627,6 +660,12 @@ svc_getreqset(fd_set *readfds)
}
void
+svc_getreqset(fd_set *readfds)
+{
+ svc_getreqset2(readfds, FD_SETSIZE);
+}
+
+void
svc_getreq_common(int fd)
{
SVCXPRT *xprt;
@@ -740,7 +779,7 @@ svc_getreq_poll(struct pollfd *pfdp, int
*/
if (p->revents & POLLNVAL) {
rwlock_wrlock(&svc_fd_lock);
- FD_CLR(p->fd, get_fdset());
+ svc_fdset_clr(p->fd);
rwlock_unlock(&svc_fd_lock);
} else
svc_getreq_common(p->fd);
Index: src/lib/libc/rpc/svc_fdset.c
diff -u src/lib/libc/rpc/svc_fdset.c:1.1 src/lib/libc/rpc/svc_fdset.c:1.2
--- src/lib/libc/rpc/svc_fdset.c:1.1 Tue Mar 5 14:55:23 2013
+++ src/lib/libc/rpc/svc_fdset.c Fri Nov 6 14:34:13 2015
@@ -1,63 +1,300 @@
-/* $NetBSD: svc_fdset.c,v 1.1 2013/03/05 19:55:23 christos Exp $ */
+/* $NetBSD: svc_fdset.c,v 1.2 2015/11/06 19:34:13 christos Exp $ */
#include <sys/cdefs.h>
-__RCSID("$NetBSD: svc_fdset.c,v 1.1 2013/03/05 19:55:23 christos Exp $");
+__RCSID("$NetBSD: svc_fdset.c,v 1.2 2015/11/06 19:34:13 christos Exp $");
+
+
+#include "reentrant.h"
+
+#include <sys/fd_set.h>
+
+#include <rpc/rpc.h>
-#include <pthread.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/select.h>
-#include "svc_fdset.h"
+struct svc_fdset {
+ fd_set *fdset;
+ int fdmax;
+ int fdsize;
+};
+
+
+/* The single threaded, one global fd_set version */
+static fd_set *__svc_fdset;
+static int svc_fdsize = 0;
+
+/*
+ * Update the old global svc_fdset if needed for binary compatibility
+ */
+#define COMPAT_UPDATE(a) \
+ do \
+ if ((a) == __svc_fdset) \
+ svc_fdset = *__svc_fdset; \
+ while (/*CONSTCOND*/0)
+
+static thread_key_t fdsetkey = -2;
+
+#ifdef FDSET_DEBUG
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <lwp.h>
+
+static void __printflike(3, 0)
+svc_header(const char *func, size_t line, const char *fmt, va_list ap)
+{
+ fprintf(stderr, "%s[%d.%d]: %s, %zu: ", getprogname(), (int)getpid(),
+ (int)_lwp_self(), func, line);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+static void __printflike(5, 6)
+svc_fdset_print(const char *func, size_t line, const fd_set *fds, int fdmax,
+ const char *fmt, ...)
+{
+ va_list ap;
+ const char *did = "";
+
+ va_start(ap, fmt);
+ svc_header(func, line, fmt, ap);
+ va_end(ap);
+
+ if (fdmax == 0)
+ fdmax = FD_SETSIZE;
+
+ fprintf(stderr, "%p[%d] <", fds, fdmax);
+ for (int i = 0; i <= fdmax; i++) {
+ if (!FD_ISSET(i, fds))
+ continue;
+ fprintf(stderr, "%s%d", did, i);
+ did = ", ";
+ }
+ fprintf(stderr, ">\n");
+}
+
+static void __printflike(3, 4)
+svc_print(const char *func, size_t line, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ svc_header(func, line, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+}
+
+#define DPRINTF_FDSET(...) svc_fdset_print(__func__, __LINE__, __VA_ARGS__)
+#define DPRINTF(...) svc_print(__func__, __LINE__, __VA_ARGS__)
+#else
+#define DPRINTF_FDSET(...)
+#define DPRINTF(...)
+#endif
+
+
+static void
+svc_fdset_free(void *v)
+{
+ struct svc_fdset *rv = v;
+ DPRINTF_FDSET(rv->fdset, 0, "free");
+
+ free(rv->fdset);
+ free(rv);
+}
+
+static fd_set *
+svc_fdset_resize(int fd, fd_set **fdset, int *fdsize)
+{
+ if (*fdset && fd < *fdsize) {
+ DPRINTF_FDSET(*fdset, 0, "keeping %d < %d",
+ fd, *fdsize);
+ return *fdset;
+ }
+
+ fd += FD_SETSIZE;
+ if (fd == 517)
+ abort();
+
+ char *newfdset = realloc(*fdset, __NFD_BYTES(fd));
+ if (newfdset == NULL)
+ return NULL;
+
+ memset(newfdset + __NFD_BYTES(*fdsize), 0,
+ __NFD_BYTES(fd) - __NFD_BYTES(*fdsize));
+
+
+ *fdset = (void *)newfdset;
+ DPRINTF_FDSET(*fdset, 0, "resize %d > %d", fd, *fdsize);
+ *fdsize = fd;
+
+ COMPAT_UPDATE(*fdset);
+
+ return *fdset;
+}
+
+static struct svc_fdset *
+svc_fdset_alloc(int fd)
+{
+ struct svc_fdset *rv;
+
+ if (fdsetkey == -1)
+ thr_keycreate(&fdsetkey, svc_fdset_free);
+
+ if ((rv = thr_getspecific(fdsetkey)) == NULL) {
+
+ rv = calloc(1, sizeof(*rv));
+ if (rv == NULL)
+ return NULL;
+
+ (void)thr_setspecific(fdsetkey, rv);
+
+ if (svc_fdsize != 0) {
+ rv->fdset = __svc_fdset;
+ DPRINTF("switching to %p", rv->fdset);
+ rv->fdmax = svc_maxfd;
+ rv->fdsize = svc_fdsize;
+
+ svc_fdsize = 0;
+ } else {
+ DPRINTF("first thread time %p", rv->fdset);
+ }
+ } else {
+ DPRINTF("again for %p", rv->fdset);
+ if (fd < rv->fdsize)
+ return rv;
+ }
+ if (svc_fdset_resize(fd, &rv->fdset, &rv->fdsize) == NULL)
+ return NULL;
+ return rv;
+}
+
+static fd_set *
+svc_fdset_get_internal(int fd)
+{
+ struct svc_fdset *rv;
+
+ if (!__isthreaded || fdsetkey == -2)
+ return svc_fdset_resize(fd, &__svc_fdset, &svc_fdsize);
+
+ rv = svc_fdset_alloc(fd);
+ if (rv == NULL)
+ return NULL;
+ return rv->fdset;
+}
+
-static pthread_key_t fdsetkey;
-static pthread_key_t fdmaxkey;
-static fd_set thefdset;
-static int thefdmax;
+/* allow each thread to have their own copy */
+void
+svc_fdset_init(int flags)
+{
+ DPRINTF("%x", flags);
+ if ((flags & SVC_FDSET_MT) && fdsetkey == -2)
+ fdsetkey = -1;
+}
void
-init_fdsets(void)
+svc_fdset_zero(void)
{
+ DPRINTF("zero");
+ fd_set *fds = svc_fdset_get_internal(0);
+ int size = svc_fdset_getsize(0);
+ memset(fds, 0, __NFD_BYTES(size));
+ *svc_fdset_getmax() = 0;
+
+ COMPAT_UPDATE(fds);
- pthread_key_create(&fdsetkey, NULL);
- pthread_key_create(&fdmaxkey, NULL);
}
void
-alloc_fdset(void)
+svc_fdset_set(int fd)
{
- fd_set *fdsetti;
- int *fdmax;
+ fd_set *fds = svc_fdset_get_internal(fd);
+ int *fdmax = svc_fdset_getmax();
+ FD_SET(fd, fds);
+ if (fd > *fdmax)
+ *fdmax = fd;
+ DPRINTF_FDSET(fds, *fdmax, "%d", fd);
- fdsetti = malloc(sizeof(*fdsetti));
- memset(fdsetti, 0, sizeof(*fdsetti));
- pthread_setspecific(fdsetkey, fdsetti);
-
- fdmax = malloc(sizeof(*fdmax));
- memset(fdmax, 0, sizeof(*fdmax));
- pthread_setspecific(fdmaxkey, fdmax);
+ COMPAT_UPDATE(fds);
+}
+
+int
+svc_fdset_isset(int fd)
+{
+ fd_set *fds = svc_fdset_get_internal(fd);
+ DPRINTF_FDSET(fds, 0, "%d", fd);
+ return FD_ISSET(fd, fds);
+}
+
+void
+svc_fdset_clr(int fd)
+{
+ fd_set *fds = svc_fdset_get_internal(fd);
+ FD_CLR(fd, fds);
+ /* XXX: update fdmax? */
+ DPRINTF_FDSET(fds, 0, "%d", fd);
+
+ COMPAT_UPDATE(fds);
}
fd_set *
-get_fdset(void)
+svc_fdset_copy(const fd_set *orig)
{
- fd_set *rv;
+ int len, fdmax;
+ fd_set *fds;
+
+ len = 0;
+ fds = 0;
+ fdmax = *svc_fdset_getmax();
+
+ DPRINTF_FDSET(orig, 0, "[orig]");
+ fds = svc_fdset_resize(fdmax, &fds, &len);
+ if (fds == NULL)
+ return NULL;
+
+ if (orig)
+ memcpy(fds, orig, __NFD_BYTES(fdmax));
+ DPRINTF_FDSET(fds, 0, "[copy]");
+ return fds;
+}
- rv = pthread_getspecific(fdsetkey);
- if (rv)
- return rv;
- else
- return &thefdset;
+fd_set *
+svc_fdset_get(void)
+{
+ fd_set *fds = svc_fdset_get_internal(0);
+ DPRINTF_FDSET(fds, 0, "get");
+ return fds;
}
int *
-get_fdsetmax(void)
+svc_fdset_getmax(void)
+{
+ struct svc_fdset *rv;
+
+ if (!__isthreaded || fdsetkey == -2)
+ return &svc_maxfd;
+
+ rv = svc_fdset_alloc(0);
+ if (rv == NULL)
+ return NULL;
+ return &rv->fdmax;
+}
+
+int
+svc_fdset_getsize(int fd)
{
- int *rv;
+ struct svc_fdset *rv;
- rv = pthread_getspecific(fdmaxkey);
- if (rv)
- return rv;
- else
- return &thefdmax;
+ if (!__isthreaded || fdsetkey == -2) {
+ if (svc_fdset_resize(fd, &__svc_fdset, &svc_fdsize) == NULL)
+ return -1;
+ else
+ return svc_fdsize;
+ }
+
+ rv = svc_fdset_alloc(fd);
+ if (rv == NULL)
+ return -1;
+ return rv->fdsize;
}
Index: src/lib/libc/rpc/svc_fdset.h
diff -u src/lib/libc/rpc/svc_fdset.h:1.1 src/lib/libc/rpc/svc_fdset.h:1.2
--- src/lib/libc/rpc/svc_fdset.h:1.1 Tue Mar 5 14:55:23 2013
+++ src/lib/libc/rpc/svc_fdset.h Fri Nov 6 14:34:13 2015
@@ -1,11 +1,4 @@
-/* $NetBSD: svc_fdset.h,v 1.1 2013/03/05 19:55:23 christos Exp $ */
-
-#ifndef _LIBC
-
-void init_fdsets(void);
-void alloc_fdset(void);
-fd_set *get_fdset(void);
-int *get_fdsetmax(void);
+/* $NetBSD: svc_fdset.h,v 1.2 2015/11/06 19:34:13 christos Exp $ */
# ifdef RUMP_RPC
# include <rump/rump.h>
@@ -23,8 +16,3 @@ int *get_fdsetmax(void);
# undef select
# define select(a, b, c, d, e) rump_sys_select(a, b, c, d, e)
# endif
-
-#else
-# define get_fdset() (&svc_fdset)
-# define get_fdsetmax() (&svc_maxfd)
-#endif
Index: src/lib/libc/rpc/svc_vc.c
diff -u src/lib/libc/rpc/svc_vc.c:1.30 src/lib/libc/rpc/svc_vc.c:1.31
--- src/lib/libc/rpc/svc_vc.c:1.30 Mon Mar 11 16:19:29 2013
+++ src/lib/libc/rpc/svc_vc.c Fri Nov 6 14:34:13 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: svc_vc.c,v 1.30 2013/03/11 20:19:29 tron Exp $ */
+/* $NetBSD: svc_vc.c,v 1.31 2015/11/06 19:34:13 christos Exp $ */
/*
* Copyright (c) 2010, Oracle America, Inc.
@@ -37,7 +37,7 @@
static char *sccsid = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC";
#else
-__RCSID("$NetBSD: svc_vc.c,v 1.30 2013/03/11 20:19:29 tron Exp $");
+__RCSID("$NetBSD: svc_vc.c,v 1.31 2015/11/06 19:34:13 christos Exp $");
#endif
#endif
@@ -312,7 +312,6 @@ rendezvous_request(SVCXPRT *xprt, struct
socklen_t len;
struct __rpc_sockinfo si;
SVCXPRT *newxprt;
- fd_set cleanfds;
_DIAGASSERT(xprt != NULL);
_DIAGASSERT(msg != NULL);
@@ -329,8 +328,10 @@ again:
* running out.
*/
if (errno == EMFILE || errno == ENFILE) {
- cleanfds = *get_fdset();
- if (__svc_clean_idle(&cleanfds, 0, FALSE))
+ fd_set *cleanfds = svc_fdset_copy(svc_fdset_get());
+ int rv = __svc_clean_idle(cleanfds, 0, FALSE);
+ free(cleanfds);
+ if (rv)
goto again;
}
return FALSE;
@@ -760,7 +761,7 @@ svc_vc_rendezvous_ops(SVCXPRT *xprt)
bool_t
__svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock)
{
- int i, ncleaned;
+ int i, ncleaned, fdmax;
SVCXPRT *xprt, *least_active;
struct timeval tv, tdiff, tmax;
struct cf_conn *cd;
@@ -769,28 +770,33 @@ __svc_clean_idle(fd_set *fds, int timeou
tmax.tv_sec = tmax.tv_usec = 0;
least_active = NULL;
rwlock_wrlock(&svc_fd_lock);
- for (i = ncleaned = 0; i <= svc_maxfd; i++) {
- if (FD_ISSET(i, fds)) {
- xprt = __svc_xports[i];
- if (xprt == NULL || xprt->xp_ops == NULL ||
- xprt->xp_ops->xp_recv != svc_vc_recv)
- continue;
- cd = (struct cf_conn *)xprt->xp_p1;
- if (!cleanblock && !cd->nonblock)
- continue;
- if (timeout == 0) {
- timersub(&tv, &cd->last_recv_time, &tdiff);
- if (timercmp(&tdiff, &tmax, >)) {
- tmax = tdiff;
- least_active = xprt;
- }
- continue;
- }
- if (tv.tv_sec - cd->last_recv_time.tv_sec > timeout) {
- __xprt_unregister_unlocked(xprt);
- __svc_vc_dodestroy(xprt);
- ncleaned++;
+ fdmax = *svc_fdset_getmax();
+ for (i = ncleaned = 0; i <= fdmax; i++) {
+ if (!svc_fdset_isset(i))
+ continue;
+
+ xprt = __svc_xports[i];
+ if (xprt == NULL || xprt->xp_ops == NULL ||
+ xprt->xp_ops->xp_recv != svc_vc_recv)
+ continue;
+
+ cd = (struct cf_conn *)xprt->xp_p1;
+ if (!cleanblock && !cd->nonblock)
+ continue;
+
+ if (timeout == 0) {
+ timersub(&tv, &cd->last_recv_time, &tdiff);
+ if (timercmp(&tdiff, &tmax, >)) {
+ tmax = tdiff;
+ least_active = xprt;
}
+ continue;
+ }
+
+ if (tv.tv_sec - cd->last_recv_time.tv_sec > timeout) {
+ __xprt_unregister_unlocked(xprt);
+ __svc_vc_dodestroy(xprt);
+ ncleaned++;
}
}
if (timeout == 0 && least_active != NULL) {