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) {

Reply via email to