Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc/rpc - Provide multi-threaded fdset's for everyone n...
details: https://anonhg.NetBSD.org/src/rev/f249e81ae442
branches: trunk
changeset: 341448:f249e81ae442
user: christos <christos%NetBSD.org@localhost>
date: Fri Nov 06 19:34:13 2015 +0000
description:
- 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.
diffstat:
lib/libc/rpc/Makefile.inc | 4 +-
lib/libc/rpc/svc.c | 115 +++++++++++-----
lib/libc/rpc/svc_fdset.c | 309 ++++++++++++++++++++++++++++++++++++++++-----
lib/libc/rpc/svc_fdset.h | 14 +-
lib/libc/rpc/svc_run.c | 36 +++-
lib/libc/rpc/svc_vc.c | 60 ++++----
6 files changed, 410 insertions(+), 128 deletions(-)
diffs (truncated from 783 to 300 lines):
diff -r 921987036c2f -r f249e81ae442 lib/libc/rpc/Makefile.inc
--- a/lib/libc/rpc/Makefile.inc Fri Nov 06 19:32:08 2015 +0000
+++ b/lib/libc/rpc/Makefile.inc Fri Nov 06 19:34:13 2015 +0000
@@ -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 @@
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
diff -r 921987036c2f -r f249e81ae442 lib/libc/rpc/svc.c
--- a/lib/libc/rpc/svc.c Fri Nov 06 19:32:08 2015 +0000
+++ b/lib/libc/rpc/svc.c Fri Nov 06 19:34:13 2015 +0000
@@ -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(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 @@
/* *************** 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 @@
_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 (!xprt_alloc(sock))
+ goto out;
+
+ __svc_xports[sock] = xprt;
+ if (sock != -1) {
+ svc_fdset_set(sock);
}
- if (sock >= FD_SETSIZE) {
- warnx("%s: socket descriptor %d too large for setsize %u",
- __func__, sock, (unsigned)FD_SETSIZE);
- goto out;
- }
- __svc_xports[sock] = xprt;
- FD_SET(sock, get_fdset());
- *get_fdsetmax() = max(*get_fdsetmax(), sock);
rwlock_unlock(&svc_fd_lock);
return (TRUE);
@@ -180,24 +207,30 @@
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 @@
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 @@
_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 @@
}
void
+svc_getreqset(fd_set *readfds)
+{
+ svc_getreqset2(readfds, FD_SETSIZE);
+}
+
+void
svc_getreq_common(int fd)
{
SVCXPRT *xprt;
@@ -740,7 +779,7 @@
*/
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);
diff -r 921987036c2f -r f249e81ae442 lib/libc/rpc/svc_fdset.c
--- a/lib/libc/rpc/svc_fdset.c Fri Nov 06 19:32:08 2015 +0000
+++ b/lib/libc/rpc/svc_fdset.c Fri Nov 06 19:34:13 2015 +0000
@@ -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 <pthread.h>
+#include <sys/fd_set.h>
+
+#include <rpc/rpc.h>
+
#include <stdlib.h>
#include <string.h>
-#include <sys/select.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);
+}
-#include "svc_fdset.h"
+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");
+}
Home |
Main Index |
Thread Index |
Old Index