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