* sunrpc/Makefile (routines): Add rpc_thread.
	(CPPFLAGS): Add -D_RPC_THREAD_SAFE.
	* sunrpc/rpc_thread.c: New file.
	* sunrpc/Versions [libc] (GLIBC_2.2.3): Export __rpc_thread_destroy.
	* sunrpc/auth_none.c: Don't use global variables.  Access state in
	thread-local storage.
	* sunrpc/clnt_perr.c: Likewise.
	* sunrpc/clnt_raw.c: Likewise.
	* sunrpc/clnt_simp.c: Likewise.
	* sunrpc/key_call.c: Likewise.
	* sunrpc/rpc_common.c: Likewise.
	* sunrpc/svc.c: Likewise.
	* sunrpc/svc_raw.c: Likewise.
	* sunrpc/svc_simple.c: Likewise.
	* sunrpc/svcauth_des.c: Likewise.
	* hurd/hurd/threadvar.h (enum __hurd_threadvar_index): Add
	_HURD_THREADVAR_RPC_VARS.
	* sysdeps/generic/bits/libc-tsd.h: Mention _LIBC_TSD_KEY_RPC_VARS.
	* include/rpc/rpc.h: Define data structures for internal thread-local
	"global" variables.
	Based on patches by Eric Norum <eric.norum@usask.ca>.
This commit is contained in:
Ulrich Drepper 2001-03-20 18:35:13 +00:00
parent 373e6a512c
commit f1e4a4a403
19 changed files with 253 additions and 67 deletions

View File

@ -1,5 +1,27 @@
2001-03-20 Ulrich Drepper <drepper@redhat.com> 2001-03-20 Ulrich Drepper <drepper@redhat.com>
* sunrpc/Makefile (routines): Add rpc_thread.
(CPPFLAGS): Add -D_RPC_THREAD_SAFE.
* sunrpc/rpc_thread.c: New file.
* sunrpc/Versions [libc] (GLIBC_2.2.3): Export __rpc_thread_destroy.
* sunrpc/auth_none.c: Don't use global variables. Access state in
thread-local storage.
* sunrpc/clnt_perr.c: Likewise.
* sunrpc/clnt_raw.c: Likewise.
* sunrpc/clnt_simp.c: Likewise.
* sunrpc/key_call.c: Likewise.
* sunrpc/rpc_common.c: Likewise.
* sunrpc/svc.c: Likewise.
* sunrpc/svc_raw.c: Likewise.
* sunrpc/svc_simple.c: Likewise.
* sunrpc/svcauth_des.c: Likewise.
* hurd/hurd/threadvar.h (enum __hurd_threadvar_index): Add
_HURD_THREADVAR_RPC_VARS.
* sysdeps/generic/bits/libc-tsd.h: Mention _LIBC_TSD_KEY_RPC_VARS.
* include/rpc/rpc.h: Define data structures for internal thread-local
"global" variables.
Based on patches by Eric Norum <eric.norum@usask.ca>.
* elf/dl-load.c: Various little optimizations. * elf/dl-load.c: Various little optimizations.
* sysdeps/unix/sysv/linux/pathconf.c (__pathconf): Return * sysdeps/unix/sysv/linux/pathconf.c (__pathconf): Return

View File

@ -1,5 +1,5 @@
/* libc-internal interface for thread-specific data. Stub version. /* libc-internal interface for thread-specific data. Stub version.
Copyright (C) 1998 Free Software Foundation, Inc. Copyright (C) 1998, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -35,6 +35,7 @@
and contains (at least): and contains (at least):
_LIBC_TSD_KEY_MALLOC _LIBC_TSD_KEY_MALLOC
_LIBC_TSD_KEY_DL_ERROR _LIBC_TSD_KEY_DL_ERROR
_LIBC_TSD_KEY_RPC_VARS
All uses must be the literal _LIBC_TSD_* name in the __libc_tsd_* macros. All uses must be the literal _LIBC_TSD_* name in the __libc_tsd_* macros.
Some implementations may not provide any enum at all and instead Some implementations may not provide any enum at all and instead
using string pasting in the macros. */ using string pasting in the macros. */

View File

@ -1,5 +1,5 @@
/* Internal per-thread variables for the Hurd. /* Internal per-thread variables for the Hurd.
Copyright (C) 1994, 95, 97, 98, 99 Free Software Foundation, Inc. Copyright (C) 1994, 95, 97, 98, 99, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -59,9 +59,10 @@ enum __hurd_threadvar_index
_HURD_THREADVAR_MIG_REPLY, /* Reply port for MiG user stub functions. */ _HURD_THREADVAR_MIG_REPLY, /* Reply port for MiG user stub functions. */
_HURD_THREADVAR_ERRNO, /* `errno' value for this thread. */ _HURD_THREADVAR_ERRNO, /* `errno' value for this thread. */
_HURD_THREADVAR_SIGSTATE, /* This thread's `struct hurd_sigstate'. */ _HURD_THREADVAR_SIGSTATE, /* This thread's `struct hurd_sigstate'. */
_HURD_THREADVAR_DYNAMIC_USER, /* Dynamically-assigned user variables. */ _HURD_THREADVAR_DYNAMIC_USER, /* Dynamically-assigned user variables. */
_HURD_THREADVAR_MALLOC, /* For use of malloc. */ _HURD_THREADVAR_MALLOC, /* For use of malloc. */
_HURD_THREADVAR_DL_ERROR, /* For use of -ldl and dynamic linker. */ _HURD_THREADVAR_DL_ERROR, /* For use of -ldl and dynamic linker. */
_HURD_THREADVAR_RPC_VARS, /* For state of RPC functions. */
_HURD_THREADVAR_MAX /* Default value for __hurd_threadvar_max. */ _HURD_THREADVAR_MAX /* Default value for __hurd_threadvar_max. */
}; };

View File

@ -1,6 +1,7 @@
2001-03-20 Ulrich Drepper <drepper@redhat.com> 2001-03-20 Ulrich Drepper <drepper@redhat.com>
* cancel.c (__pthread_perform_cleanup): Call __rpc_thread_destroy. * cancel.c (__pthread_perform_cleanup): Call __rpc_thread_destroy.
* sysdeps/pthread/bits/libc-tsd.h: Define _LIBC_TSD_KEY_VARS.
2001-03-18 Ulrich Drepper <drepper@redhat.com> 2001-03-18 Ulrich Drepper <drepper@redhat.com>

View File

@ -1,5 +1,5 @@
/* libc-internal interface for thread-specific data. LinuxThreads version. /* libc-internal interface for thread-specific data. LinuxThreads version.
Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -24,6 +24,7 @@
/* Fast thread-specific data internal to libc. */ /* Fast thread-specific data internal to libc. */
enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0, enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0,
_LIBC_TSD_KEY_DL_ERROR, _LIBC_TSD_KEY_DL_ERROR,
_LIBC_TSD_KEY_RPC_VARS,
_LIBC_TSD_KEY_N }; _LIBC_TSD_KEY_N };
extern void *(*__libc_internal_tsd_get) (enum __libc_tsd_key_t) __THROW; extern void *(*__libc_internal_tsd_get) (enum __libc_tsd_key_t) __THROW;

View File

@ -60,7 +60,7 @@ routines := auth_none auth_unix authuxprot bindrsvprt \
clnt_gen clnt_perr clnt_raw clnt_simp clnt_tcp \ clnt_gen clnt_perr clnt_raw clnt_simp clnt_tcp \
clnt_udp rpc_dtable get_myaddr getrpcport \ clnt_udp rpc_dtable get_myaddr getrpcport \
pmap_clnt pm_getmaps pm_getport pmap_prot \ pmap_clnt pm_getmaps pm_getport pmap_prot \
pmap_prot2 pmap_rmt rpc_prot rpc_common rpc_cmsg \ pmap_prot2 pmap_rmt rpc_prot rpc_common rpc_cmsg rpc_thread \
svc svc_auth svc_authux svc_raw svc_run svc_simple \ svc svc_auth svc_authux svc_raw svc_run svc_simple \
svc_tcp svc_udp xdr xdr_array xdr_float xdr_mem \ svc_tcp svc_udp xdr xdr_array xdr_float xdr_mem \
xdr_rec xdr_ref xdr_stdio publickey xdr_sizeof \ xdr_rec xdr_ref xdr_stdio publickey xdr_sizeof \
@ -116,6 +116,7 @@ CFLAGS-xkey_prot.c = -Wno-unused
ifeq (yes,$(have_doors)) ifeq (yes,$(have_doors))
CPPFLAGS-key_call.c += -DHAVE_DOORS=1 CPPFLAGS-key_call.c += -DHAVE_DOORS=1
endif endif
CPPFLAGS += -D_RPC_THREAD_SAFE_
include ../Rules include ../Rules

View File

@ -109,4 +109,7 @@ libc {
GLIBC_2.2 { GLIBC_2.2 {
svc_getreq_common; svc_getreq_poll; svc_max_pollfd; svc_pollfd; svc_getreq_common; svc_getreq_poll; svc_max_pollfd; svc_pollfd;
} }
GLIBC_2.2.3 {
__rpc_thread_destroy;
}
} }

View File

@ -35,8 +35,7 @@
* credentials and verifiers to remote systems. * credentials and verifiers to remote systems.
*/ */
#include <rpc/types.h> #include <rpc/rpc.h>
#include <rpc/auth.h>
#define MAX_MARSHEL_SIZE 20 #define MAX_MARSHEL_SIZE 20
@ -57,24 +56,29 @@ static struct auth_ops ops = {
authnone_destroy authnone_destroy
}; };
static struct authnone_private struct authnone_private_s {
{
AUTH no_client; AUTH no_client;
char marshalled_client[MAX_MARSHEL_SIZE]; char marshalled_client[MAX_MARSHEL_SIZE];
u_int mcnt; u_int mcnt;
} *authnone_private; };
#ifdef _RPC_THREAD_SAFE_
#define authnone_private ((struct authnone_private_ *)RPC_THREAD_VARIABLE(authnone_private_s))
#else
static struct authnone_private_s *authnone_private;
#endif
AUTH * AUTH *
authnone_create (void) authnone_create (void)
{ {
struct authnone_private *ap = authnone_private; struct authnone_private_s *ap;
XDR xdr_stream; XDR xdr_stream;
XDR *xdrs; XDR *xdrs;
if (ap == 0) ap = (struct authnone_private_s *) authnone_private;
if (ap == NULL)
{ {
ap = (struct authnone_private *) calloc (1, sizeof (*ap)); ap = (struct authnone_private_s *) calloc (1, sizeof (*ap));
if (ap == 0) if (ap == NULL)
return NULL; return NULL;
authnone_private = ap; authnone_private = ap;
} }
@ -97,10 +101,11 @@ authnone_create (void)
static bool_t static bool_t
authnone_marshal (AUTH *client, XDR *xdrs) authnone_marshal (AUTH *client, XDR *xdrs)
{ {
struct authnone_private *ap = authnone_private; struct authnone_private_s *ap;
if (ap == 0) ap = (struct authnone_private_s *) authnone_private;
return 0; if (ap == NULL)
return FALSE;
return (*xdrs->x_ops->x_putbytes) (xdrs, ap->marshalled_client, ap->mcnt); return (*xdrs->x_ops->x_putbytes) (xdrs, ap->marshalled_client, ap->mcnt);
} }

View File

@ -40,9 +40,7 @@ static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <libintl.h> #include <libintl.h>
#include <rpc/types.h> #include <rpc/rpc.h>
#include <rpc/auth.h>
#include <rpc/clnt.h>
#ifdef USE_IN_LIBIO #ifdef USE_IN_LIBIO
# include <libio/iolibio.h> # include <libio/iolibio.h>
@ -51,7 +49,16 @@ static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
static char *auth_errmsg (enum auth_stat stat) internal_function; static char *auth_errmsg (enum auth_stat stat) internal_function;
#ifdef _RPC_THREAD_SAFE_
/*
* Making buf a preprocessor macro requires renaming the local
* buf variable in a few functions. Overriding a global variable
* with a local variable of the same name is a bad idea, anyway.
*/
#define buf ((char *)RPC_THREAD_VARIABLE(clnt_perr_buf_s))
#else
static char *buf; static char *buf;
#endif
static char * static char *
_buf (void) _buf (void)
@ -67,7 +74,7 @@ _buf (void)
char * char *
clnt_sperror (CLIENT * rpch, const char *msg) clnt_sperror (CLIENT * rpch, const char *msg)
{ {
char buf[1024]; char chrbuf[1024];
struct rpc_err e; struct rpc_err e;
char *err; char *err;
char *str = _buf (); char *str = _buf ();
@ -103,7 +110,7 @@ clnt_sperror (CLIENT * rpch, const char *msg)
case RPC_CANTSEND: case RPC_CANTSEND:
case RPC_CANTRECV: case RPC_CANTRECV:
len = sprintf (str, "; errno = %s", __strerror_r (e.re_errno, len = sprintf (str, "; errno = %s", __strerror_r (e.re_errno,
buf, sizeof buf)); chrbuf, sizeof chrbuf));
str += len; str += len;
break; break;
@ -281,7 +288,7 @@ clnt_perrno (enum clnt_stat num)
char * char *
clnt_spcreateerror (const char *msg) clnt_spcreateerror (const char *msg)
{ {
char buf[1024]; char chrbuf[1024];
char *str = _buf (); char *str = _buf ();
char *cp; char *cp;
int len; int len;
@ -301,7 +308,7 @@ clnt_spcreateerror (const char *msg)
case RPC_SYSTEMERROR: case RPC_SYSTEMERROR:
cp = stpcpy (stpcpy (cp, " - "), cp = stpcpy (stpcpy (cp, " - "),
__strerror_r (rpc_createerr.cf_error.re_errno, __strerror_r (rpc_createerr.cf_error.re_errno,
buf, sizeof buf)); chrbuf, sizeof chrbuf));
break; break;
default: default:
break; break;

View File

@ -52,15 +52,19 @@ static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
/* /*
* This is the "network" we will be moving stuff over. * This is the "network" we will be moving stuff over.
*/ */
static struct clntraw_private struct clntraw_private_s
{ {
CLIENT client_object; CLIENT client_object;
XDR xdr_stream; XDR xdr_stream;
char _raw_buf[UDPMSGSIZE]; char _raw_buf[UDPMSGSIZE];
char mashl_callmsg[MCALL_MSG_SIZE]; char mashl_callmsg[MCALL_MSG_SIZE];
u_int mcnt; u_int mcnt;
} };
*clntraw_private; #ifdef _RPC_THREAD_SAFE_
#define clntraw_private ((struct clntraw_private_s *)RPC_THREAD_VARIABLE(clntraw_private_s))
#else
static struct clntraw_private_s *clntraw_private;
#endif
static enum clnt_stat clntraw_call (CLIENT *, u_long, xdrproc_t, caddr_t, static enum clnt_stat clntraw_call (CLIENT *, u_long, xdrproc_t, caddr_t,
xdrproc_t, caddr_t, struct timeval); xdrproc_t, caddr_t, struct timeval);
@ -86,14 +90,14 @@ static struct clnt_ops client_ops =
CLIENT * CLIENT *
clntraw_create (u_long prog, u_long vers) clntraw_create (u_long prog, u_long vers)
{ {
struct clntraw_private *clp = clntraw_private; struct clntraw_private_s *clp = clntraw_private;
struct rpc_msg call_msg; struct rpc_msg call_msg;
XDR *xdrs = &clp->xdr_stream; XDR *xdrs = &clp->xdr_stream;
CLIENT *client = &clp->client_object; CLIENT *client = &clp->client_object;
if (clp == 0) if (clp == 0)
{ {
clp = (struct clntraw_private *) calloc (1, sizeof (*clp)); clp = (struct clntraw_private_s *) calloc (1, sizeof (*clp));
if (clp == 0) if (clp == 0)
return (0); return (0);
clntraw_private = clp; clntraw_private = clp;
@ -136,7 +140,7 @@ clntraw_call (h, proc, xargs, argsp, xresults, resultsp, timeout)
caddr_t resultsp; caddr_t resultsp;
struct timeval timeout; struct timeval timeout;
{ {
struct clntraw_private *clp = clntraw_private; struct clntraw_private_s *clp = clntraw_private;
XDR *xdrs = &clp->xdr_stream; XDR *xdrs = &clp->xdr_stream;
struct rpc_msg msg; struct rpc_msg msg;
enum clnt_stat status; enum clnt_stat status;
@ -220,7 +224,7 @@ clntraw_freeres (cl, xdr_res, res_ptr)
xdrproc_t xdr_res; xdrproc_t xdr_res;
caddr_t res_ptr; caddr_t res_ptr;
{ {
struct clntraw_private *clp = clntraw_private; struct clntraw_private_s *clp = clntraw_private;
XDR *xdrs = &clp->xdr_stream; XDR *xdrs = &clp->xdr_stream;
bool_t rval; bool_t rval;

View File

@ -47,20 +47,24 @@ static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";
#include <netdb.h> #include <netdb.h>
#include <string.h> #include <string.h>
static struct callrpc_private struct callrpc_private_s
{ {
CLIENT *client; CLIENT *client;
int socket; int socket;
u_long oldprognum, oldversnum, valid; u_long oldprognum, oldversnum, valid;
char *oldhost; char *oldhost;
} };
*callrpc_private; #ifdef _RPC_THREAD_SAFE_
#define callrpc_private ((struct callrpc_private_s *)RPC_THREAD_VARIABLE(callrpc_private_s))
#else
static struct callrpc_private_s *callrpc_private;
#endif
int int
callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum, callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
xdrproc_t inproc, const char *in, xdrproc_t outproc, char *out) xdrproc_t inproc, const char *in, xdrproc_t outproc, char *out)
{ {
struct callrpc_private *crp = callrpc_private; struct callrpc_private_s *crp = callrpc_private;
struct sockaddr_in server_addr; struct sockaddr_in server_addr;
enum clnt_stat clnt_stat; enum clnt_stat clnt_stat;
struct hostent hostbuf, *hp; struct hostent hostbuf, *hp;
@ -68,7 +72,7 @@ callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
if (crp == 0) if (crp == 0)
{ {
crp = (struct callrpc_private *) calloc (1, sizeof (*crp)); crp = (struct callrpc_private_s *) calloc (1, sizeof (*crp));
if (crp == 0) if (crp == 0)
return 0; return 0;
callrpc_private = crp; callrpc_private = crp;
@ -141,3 +145,17 @@ callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
crp->valid = 0; crp->valid = 0;
return (int) clnt_stat; return (int) clnt_stat;
} }
#ifdef _RPC_THREAD_SAFE_
void
__rpc_thread_clnt_cleanup (void)
{
struct callrpc_private_s *rcp = RPC_THREAD_VARIABLE(callrpc_private_s);
if (rcp) {
if (rcp->client)
CLNT_DESTROY (rcp->client);
free (rcp);
}
}
#endif /* _RPC_THREAD_SAFE_ */

View File

@ -359,7 +359,11 @@ struct key_call_private {
pid_t pid; /* process-id at moment of creation */ pid_t pid; /* process-id at moment of creation */
uid_t uid; /* user-id at last authorization */ uid_t uid; /* user-id at last authorization */
}; };
#ifdef _RPC_THREAD_SAFE_
#define key_call_private_main ((struct key_call_private *)RPC_THREAD_VARIABLE(key_call_private_s))
#else
static struct key_call_private *key_call_private_main; static struct key_call_private *key_call_private_main;
#endif
__libc_lock_define_initialized (static, keycall_lock) __libc_lock_define_initialized (static, keycall_lock)
/* /*
@ -610,3 +614,17 @@ key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
return key_call_keyenvoy (proc, xdr_arg, arg, xdr_rslt, rslt); return key_call_keyenvoy (proc, xdr_arg, arg, xdr_rslt, rslt);
#endif #endif
} }
#ifdef _RPC_THREAD_SAFE_
void
__rpc_thread_key_cleanup (void)
{
struct key_call_private *kcp = RPC_THREAD_VARIABLE(key_call_private_s);
if (kcp) {
if (kcp->client)
clnt_destroy(kcp->client);
free (kcp);
}
}
#endif /* _RPC_THREAD_SAFE_ */

View File

@ -27,6 +27,14 @@
* Mountain View, California 94043 * Mountain View, California 94043
*/ */
#include <rpc/rpc.h> #include <rpc/rpc.h>
#ifdef _RPC_THREAD_SAFE_
#undef svc_fdset
#undef rpc_createerr
#undef svc_pollfd
#undef svc_max_pollfd
#endif /* _RPC_THREAD_SAFE_ */
/* /*
* This file should only contain common data (global data) that is exported * This file should only contain common data (global data) that is exported
* by public interfaces * by public interfaces

55
sunrpc/rpc_thread.c Normal file
View File

@ -0,0 +1,55 @@
#include <stdio.h>
#include <bits/libc-lock.h>
#include <rpc/rpc.h>
#include <assert.h>
#include <bits/libc-lock.h>
#include <bits/libc-tsd.h>
#ifdef _RPC_THREAD_SAFE_
/* Variable used in non-threaded applications. */
static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem;
static struct rpc_thread_variables *__libc_tsd_RPC_VARS_data =
&__libc_tsd_RPC_VARS_mem;
/*
* Task-variable destructor
*/
void
__rpc_thread_destroy (void)
{
struct rpc_thread_variables *tvp = __rpc_thread_variables();
if (tvp != NULL) {
__rpc_thread_svc_cleanup ();
__rpc_thread_clnt_cleanup ();
__rpc_thread_key_cleanup ();
free (tvp->authnone_private_s);
free (tvp->clnt_perr_buf_s);
free (tvp->clntraw_private_s);
free (tvp->svcraw_private_s);
free (tvp->authdes_cache_s);
free (tvp->authdes_lru_s);
free (tvp);
}
}
struct rpc_thread_variables *
__rpc_thread_variables (void)
{
struct rpc_thread_variables *tvp;
tvp = __libc_tsd_get (RPC_VARS);
if (tvp == NULL) {
tvp = calloc (1, sizeof *tvp);
if (tvp != NULL)
__libc_tsd_set (RPC_VARS, tvp);
else
tvp = __libc_tsd_RPC_VARS_data;
}
return tvp;
}
#endif /* _RPC_THREAD_SAFE_ */

View File

@ -43,7 +43,11 @@
#include <rpc/pmap_clnt.h> #include <rpc/pmap_clnt.h>
#include <sys/poll.h> #include <sys/poll.h>
#ifdef _RPC_THREAD_SAFE_
#define xports ((SVCXPRT **)RPC_THREAD_VARIABLE(svc_xports_s))
#else
static SVCXPRT **xports; static SVCXPRT **xports;
#endif
#define NULL_SVC ((struct svc_callout *)0) #define NULL_SVC ((struct svc_callout *)0)
#define RQCRED_SIZE 400 /* this size is excessive */ #define RQCRED_SIZE 400 /* this size is excessive */
@ -52,12 +56,17 @@ static SVCXPRT **xports;
Each entry represents a set of procedures (an rpc program). Each entry represents a set of procedures (an rpc program).
The dispatch routine takes request structs and runs the The dispatch routine takes request structs and runs the
appropriate procedure. */ appropriate procedure. */
static struct svc_callout { struct svc_callout {
struct svc_callout *sc_next; struct svc_callout *sc_next;
rpcprog_t sc_prog; rpcprog_t sc_prog;
rpcvers_t sc_vers; rpcvers_t sc_vers;
void (*sc_dispatch) (struct svc_req *, SVCXPRT *); void (*sc_dispatch) (struct svc_req *, SVCXPRT *);
} *svc_head; };
#ifdef _RPC_THREAD_SAFE_
#define svc_head ((struct svc_callout *)RPC_THREAD_VARIABLE(svc_head_s))
#else
static struct svc_callout *svc_head;
#endif
/* *************** SVCXPRT related stuff **************** */ /* *************** SVCXPRT related stuff **************** */
@ -464,3 +473,16 @@ svc_getreq_common (const int fd)
} }
while (stat == XPRT_MOREREQS); while (stat == XPRT_MOREREQS);
} }
#ifdef _RPC_THREAD_SAFE_
void
__rpc_thread_svc_cleanup (void)
{
struct svc_callout *svcp;
while ((svcp = svc_head) != NULL)
svc_unregister (svcp->sc_prog, svcp->sc_vers);
}
#endif /* _RPC_THREAD_SAFE_ */

View File

@ -46,14 +46,18 @@ static char sccsid[] = "@(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";
/* /*
* This is the "network" that we will be moving data over * This is the "network" that we will be moving data over
*/ */
static struct svcraw_private struct svcraw_private_s
{ {
char _raw_buf[UDPMSGSIZE]; char _raw_buf[UDPMSGSIZE];
SVCXPRT server; SVCXPRT server;
XDR xdr_stream; XDR xdr_stream;
char verf_body[MAX_AUTH_BYTES]; char verf_body[MAX_AUTH_BYTES];
} };
*svcraw_private; #ifdef _RPC_THREAD_SAFE_
#define svcraw_private ((struct svcraw_private_s *)RPC_THREAD_VARIABLE(svcraw_private_s))
#else
static struct svcraw_private_s *svcraw_private;
#endif
static bool_t svcraw_recv (SVCXPRT *, struct rpc_msg *); static bool_t svcraw_recv (SVCXPRT *, struct rpc_msg *);
static enum xprt_stat svcraw_stat (SVCXPRT *); static enum xprt_stat svcraw_stat (SVCXPRT *);
@ -75,11 +79,11 @@ static struct xp_ops server_ops =
SVCXPRT * SVCXPRT *
svcraw_create (void) svcraw_create (void)
{ {
struct svcraw_private *srp = svcraw_private; struct svcraw_private_s *srp = svcraw_private;
if (srp == 0) if (srp == 0)
{ {
srp = (struct svcraw_private *) calloc (1, sizeof (*srp)); srp = (struct svcraw_private_s *) calloc (1, sizeof (*srp));
if (srp == 0) if (srp == 0)
return NULL; return NULL;
} }
@ -102,7 +106,7 @@ svcraw_recv (xprt, msg)
SVCXPRT *xprt; SVCXPRT *xprt;
struct rpc_msg *msg; struct rpc_msg *msg;
{ {
struct svcraw_private *srp = svcraw_private; struct svcraw_private_s *srp = svcraw_private;
XDR *xdrs; XDR *xdrs;
if (srp == 0) if (srp == 0)
@ -118,7 +122,7 @@ svcraw_recv (xprt, msg)
static bool_t static bool_t
svcraw_reply (SVCXPRT *xprt, struct rpc_msg *msg) svcraw_reply (SVCXPRT *xprt, struct rpc_msg *msg)
{ {
struct svcraw_private *srp = svcraw_private; struct svcraw_private_s *srp = svcraw_private;
XDR *xdrs; XDR *xdrs;
if (srp == 0) if (srp == 0)
@ -135,7 +139,7 @@ svcraw_reply (SVCXPRT *xprt, struct rpc_msg *msg)
static bool_t static bool_t
svcraw_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) svcraw_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
{ {
struct svcraw_private *srp = svcraw_private; struct svcraw_private_s *srp = svcraw_private;
if (srp == 0) if (srp == 0)
return FALSE; return FALSE;
@ -145,7 +149,7 @@ svcraw_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
static bool_t static bool_t
svcraw_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) svcraw_freeargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
{ {
struct svcraw_private *srp = svcraw_private; struct svcraw_private_s *srp = svcraw_private;
XDR *xdrs; XDR *xdrs;
if (srp == 0) if (srp == 0)

View File

@ -51,24 +51,33 @@ static char sccsid[] = "@(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";
# define fputs(s, f) _IO_fputs (s, f) # define fputs(s, f) _IO_fputs (s, f)
#endif #endif
static struct proglst struct proglst_
{ {
char *(*p_progname) (char *); char *(*p_progname) (char *);
int p_prognum; int p_prognum;
int p_procnum; int p_procnum;
xdrproc_t p_inproc, p_outproc; xdrproc_t p_inproc, p_outproc;
struct proglst *p_nxt; struct proglst_ *p_nxt;
} };
*proglst; #ifdef _RPC_THREAD_SAFE_
#define proglst ((struct proglst_ *)RPC_THREAD_VARIABLE(svcsimple_proglst_s))
#else
static struct proglst_ *proglst;
#endif
static void universal (struct svc_req *rqstp, SVCXPRT *transp);
static void universal (struct svc_req *rqstp, SVCXPRT *transp_s);
#ifdef _RPC_THREAD_SAFE_
#define transp ((SVCXPRT *)RPC_THREAD_VARIABLE(svcsimple_transp_s))
#else
static SVCXPRT *transp; static SVCXPRT *transp;
#endif
int int
registerrpc (u_long prognum, u_long versnum, u_long procnum, registerrpc (u_long prognum, u_long versnum, u_long procnum,
char *(*progname) (char *), xdrproc_t inproc, xdrproc_t outproc) char *(*progname) (char *), xdrproc_t inproc, xdrproc_t outproc)
{ {
struct proglst *pl; struct proglst_ *pl;
if (procnum == NULLPROC) if (procnum == NULLPROC)
{ {
@ -93,7 +102,7 @@ registerrpc (u_long prognum, u_long versnum, u_long procnum,
prognum, versnum); prognum, versnum);
return -1; return -1;
} }
pl = (struct proglst *) malloc (sizeof (struct proglst)); pl = (struct proglst_ *) malloc (sizeof (struct proglst_));
if (pl == NULL) if (pl == NULL)
{ {
(void) fprintf (stderr, _("registerrpc: out of memory\n")); (void) fprintf (stderr, _("registerrpc: out of memory\n"));
@ -110,19 +119,19 @@ registerrpc (u_long prognum, u_long versnum, u_long procnum,
} }
static void static void
universal (struct svc_req *rqstp, SVCXPRT *transp) universal (struct svc_req *rqstp, SVCXPRT *transp_l)
{ {
int prog, proc; int prog, proc;
char *outdata; char *outdata;
char xdrbuf[UDPMSGSIZE]; char xdrbuf[UDPMSGSIZE];
struct proglst *pl; struct proglst_ *pl;
/* /*
* enforce "procnum 0 is echo" convention * enforce "procnum 0 is echo" convention
*/ */
if (rqstp->rq_proc == NULLPROC) if (rqstp->rq_proc == NULLPROC)
{ {
if (svc_sendreply (transp, (xdrproc_t)xdr_void, (char *) NULL) == FALSE) if (svc_sendreply (transp_l, (xdrproc_t)xdr_void, (char *) NULL) == FALSE)
{ {
(void) fprintf (stderr, "xxx\n"); (void) fprintf (stderr, "xxx\n");
exit (1); exit (1);
@ -136,16 +145,16 @@ universal (struct svc_req *rqstp, SVCXPRT *transp)
{ {
/* decode arguments into a CLEAN buffer */ /* decode arguments into a CLEAN buffer */
__bzero (xdrbuf, sizeof (xdrbuf)); /* required ! */ __bzero (xdrbuf, sizeof (xdrbuf)); /* required ! */
if (!svc_getargs (transp, pl->p_inproc, xdrbuf)) if (!svc_getargs (transp_l, pl->p_inproc, xdrbuf))
{ {
svcerr_decode (transp); svcerr_decode (transp_l);
return; return;
} }
outdata = (*(pl->p_progname)) (xdrbuf); outdata = (*(pl->p_progname)) (xdrbuf);
if (outdata == NULL && pl->p_outproc != (xdrproc_t)xdr_void) if (outdata == NULL && pl->p_outproc != (xdrproc_t)xdr_void)
/* there was an error */ /* there was an error */
return; return;
if (!svc_sendreply (transp, pl->p_outproc, outdata)) if (!svc_sendreply (transp_l, pl->p_outproc, outdata))
{ {
(void) fprintf (stderr, (void) fprintf (stderr,
_ ("trouble replying to prog %d\n"), _ ("trouble replying to prog %d\n"),
@ -153,7 +162,7 @@ universal (struct svc_req *rqstp, SVCXPRT *transp)
exit (1); exit (1);
} }
/* free the decoded arguments */ /* free the decoded arguments */
(void) svc_freeargs (transp, pl->p_inproc, xdrbuf); (void) svc_freeargs (transp_l, pl->p_inproc, xdrbuf);
return; return;
} }
(void) fprintf (stderr, _ ("never registered prog %d\n"), prog); (void) fprintf (stderr, _ ("never registered prog %d\n"), prog);

View File

@ -46,7 +46,7 @@
#include <string.h> #include <string.h>
#include <sys/param.h> #include <sys/param.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <rpc/types.h> #include <rpc/rpc.h>
#include <rpc/xdr.h> #include <rpc/xdr.h>
#include <rpc/auth.h> #include <rpc/auth.h>
#include <rpc/auth_des.h> #include <rpc/auth_des.h>
@ -71,8 +71,13 @@ struct cache_entry
struct rpc_timeval laststamp; /* detect replays of creds */ struct rpc_timeval laststamp; /* detect replays of creds */
char *localcred; /* generic local credential */ char *localcred; /* generic local credential */
}; };
static struct cache_entry *authdes_cache /* [AUTHDES_CACHESZ] */ ; #ifdef _RPC_THREAD_SAFE_
static int *authdes_lru /* [AUTHDES_CACHESZ] */ ; #define authdes_cache ((struct cache_entry *)RPC_THREAD_VARIABLE(authdes_cache_s))
#define authdes_lru ((int *)RPC_THREAD_VARIABLE(authdes_lru_s))
#else
static struct cache_entry *authdes_cache;
static int *authdes_lru;
#endif
static void cache_init (void) internal_function; /* initialize the cache */ static void cache_init (void) internal_function; /* initialize the cache */
static short cache_spot (des_block *, char *, struct rpc_timeval *) static short cache_spot (des_block *, char *, struct rpc_timeval *)

View File

@ -1,5 +1,5 @@
/* libc-internal interface for thread-specific data. Stub version. /* libc-internal interface for thread-specific data. Stub version.
Copyright (C) 1998 Free Software Foundation, Inc. Copyright (C) 1998, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -35,6 +35,7 @@
and contains (at least): and contains (at least):
_LIBC_TSD_KEY_MALLOC _LIBC_TSD_KEY_MALLOC
_LIBC_TSD_KEY_DL_ERROR _LIBC_TSD_KEY_DL_ERROR
_LIBC_TSD_KEY_RPC_VARS
All uses must be the literal _LIBC_TSD_* name in the __libc_tsd_* macros. All uses must be the literal _LIBC_TSD_* name in the __libc_tsd_* macros.
Some implementations may not provide any enum at all and instead Some implementations may not provide any enum at all and instead
using string pasting in the macros. */ using string pasting in the macros. */