xref: /netbsd-src/lib/libc/rpc/mt_misc.c (revision 5e4c038a45edbc7d63b7c2daa76e29f88b64a4e3)
1 /*	$NetBSD: mt_misc.c,v 1.1 2000/06/02 23:11:11 fvdl Exp $	*/
2 
3 /*
4  *	Define and initialize MT data for libnsl.
5  *	The _libnsl_lock_init() function below is the library's .init handler.
6  */
7 
8 /* #pragma ident	"@(#)mt_misc.c	1.24	93/04/29 SMI" */
9 
10 #include	"reentrant.h"
11 #include	<rpc/rpc.h>
12 #include	<sys/time.h>
13 #include	<stdlib.h>
14 
15 #ifdef _REENT
16 
17 /*
18  * XXX fvdl - this needs to be done right when implementing a thread-safe
19  * libc.
20  */
21 
22 rwlock_t	svc_lock;	/* protects the services list (svc.c) */
23 rwlock_t	svc_fd_lock;	/* protects svc_fdset and the xports[] array */
24 rwlock_t	rpcbaddr_cache_lock; /* protects the RPCBIND address cache */
25 static rwlock_t	*rwlock_table[] = {
26 	&svc_lock,
27 	&svc_fd_lock,
28 	&rpcbaddr_cache_lock
29 };
30 
31 mutex_t	authdes_lock;		/* protects authdes cache (svcauth_des.c) */
32 mutex_t	authnone_lock;		/* auth_none.c serialization */
33 mutex_t	authsvc_lock;		/* protects the Auths list (svc_auth.c) */
34 mutex_t	clnt_fd_lock;		/* protects client-side fd lock array */
35 mutex_t	clntraw_lock;		/* clnt_raw.c serialization */
36 mutex_t	dname_lock;		/* domainname and domain_fd (getdname.c) */
37 				/*	and default_domain (rpcdname.c) */
38 mutex_t	dupreq_lock;		/* dupreq variables (svc_dg.c) */
39 mutex_t	keyserv_lock;		/* protects first_time and hostname */
40 				/*	(key_call.c) */
41 mutex_t	libnsl_trace_lock;	/* serializes rpc_trace() (rpc_trace.c) */
42 mutex_t	loopnconf_lock;		/* loopnconf (rpcb_clnt.c) */
43 mutex_t	ops_lock;		/* serializes ops initializations */
44 mutex_t	portnum_lock;		/* protects ``port'' static in bindresvport() */
45 mutex_t	proglst_lock;		/* protects proglst list (svc_simple.c) */
46 mutex_t	rpcsoc_lock;		/* serializes clnt_com_create() (rpc_soc.c) */
47 mutex_t	svcraw_lock;		/* svc_raw.c serialization */
48 mutex_t	tsd_lock;		/* protects TSD key creation */
49 mutex_t	xprtlist_lock;		/* xprtlist (svc_generic.c) */
50 mutex_t serialize_pkey;		/* serializes calls to public key routines */
51 
52 
53 static mutex_t	*mutex_table[] = {
54 	&authdes_lock,
55 	&authnone_lock,
56 	&authsvc_lock,
57 	&clnt_fd_lock,
58 	&clntraw_lock,
59 	&dname_lock,
60 	&dupreq_lock,
61 	&keyserv_lock,
62 	&libnsl_trace_lock,
63 	&loopnconf_lock,
64 	&ops_lock,
65 	&portnum_lock,
66 	&proglst_lock,
67 	&rpcsoc_lock,
68 	&svcraw_lock,
69 	&tsd_lock,
70 	&xprtlist_lock,
71 	&serialize_pkey
72 };
73 
74 int __rpc_lock_value;
75 
76 #pragma init(_libnsl_lock_init)
77 
78 void
79 _libnsl_lock_init()
80 {
81 	int	i;
82 
83 /* _thr_main() returns -1 if libthread no linked in */
84 
85 	if (_thr_main() == -1)
86 		lock_value = 0;
87 	else
88 		lock_value = 1;
89 
90 	for (i = 0; i < sizeof (mutex_table) / sizeof (mutex_table[0]); i++)
91 		mutex_init(mutex_table[i], 0, (void *) 0);
92 
93 	for (i = 0; i < sizeof (rwlock_table) / sizeof (rwlock_table[0]); i++)
94 		rwlock_init(rwlock_table[i], 0, (void *) 0);
95 }
96 
97 #endif /* _REENT */
98 
99 
100 #undef	rpc_createerr
101 
102 struct rpc_createerr rpc_createerr;
103 
104 struct rpc_createerr *
105 __rpc_createerr()
106 {
107 #ifdef _REENT
108 	static thread_key_t rce_key = 0;
109 	struct rpc_createerr *rce_addr = 0;
110 
111 	if (_thr_main())
112 		return (&rpc_createerr);
113 	if (_thr_getspecific(rce_key, (void **) &rce_addr) != 0) {
114 		mutex_lock(&tsd_lock);
115 		if (_thr_keycreate(&rce_key, free) != 0) {
116 			mutex_unlock(&tsd_lock);
117 			return (&rpc_createerr);
118 		}
119 		mutex_unlock(&tsd_lock);
120 	}
121 	if (!rce_addr) {
122 		rce_addr = (struct rpc_createerr *)
123 			malloc(sizeof (struct rpc_createerr));
124 		if (_thr_setspecific(rce_key, (void *) rce_addr) != 0) {
125 			if (rce_addr)
126 				free(rce_addr);
127 			return (&rpc_createerr);
128 		}
129 		memset(rce_addr, 0, sizeof (struct rpc_createerr));
130 		return (rce_addr);
131 	}
132 	return (rce_addr);
133 #else
134 	return &rpc_createerr;
135 #endif
136 }
137