svn commit: r205450 - stable/7/lib/libc/rpc
John Baldwin
jhb at FreeBSD.org
Mon Mar 22 15:54:57 UTC 2010
Author: jhb
Date: Mon Mar 22 15:54:56 2010
New Revision: 205450
URL: http://svn.freebsd.org/changeset/base/205450
Log:
MFC 204950,205020:
Use thr_once() with once_t controls to initialize various thread_key_t
objects used to provide per-thread storage in the RPC code. Almost all
of these used double-checking with a dedicated mutex (tsd_lock) to do this
before. However, that is not always safe with more relaxed memory orders.
There were also other bugs, such as one in __rpc_createrr() that caused a
new key to be allocated each time __rpc_createrr() was invoked.
Modified:
stable/7/lib/libc/rpc/Symbol.map
stable/7/lib/libc/rpc/clnt_simple.c
stable/7/lib/libc/rpc/getnetconfig.c
stable/7/lib/libc/rpc/key_call.c
stable/7/lib/libc/rpc/mt_misc.c
stable/7/lib/libc/rpc/mt_misc.h
stable/7/lib/libc/rpc/rpc_generic.c
stable/7/lib/libc/rpc/rpc_soc.c
Directory Properties:
stable/7/lib/libc/ (props changed)
stable/7/lib/libc/stdtime/ (props changed)
Modified: stable/7/lib/libc/rpc/Symbol.map
==============================================================================
--- stable/7/lib/libc/rpc/Symbol.map Mon Mar 22 15:52:26 2010 (r205449)
+++ stable/7/lib/libc/rpc/Symbol.map Mon Mar 22 15:54:56 2010 (r205450)
@@ -239,9 +239,5 @@ FBSDprivate_1.0 {
__key_encryptsession_pk_LOCAL;
__key_decryptsession_pk_LOCAL;
__key_gendes_LOCAL;
- __tsd_lock; /*
- * Why does usr.bin/rpcinfo/Makefile need rpc_generic.c?
- * Remove this hack if rpcinfo stops building with it.
- */
__svc_clean_idle;
};
Modified: stable/7/lib/libc/rpc/clnt_simple.c
==============================================================================
--- stable/7/lib/libc/rpc/clnt_simple.c Mon Mar 22 15:52:26 2010 (r205449)
+++ stable/7/lib/libc/rpc/clnt_simple.c Mon Mar 22 15:54:56 2010 (r205450)
@@ -76,7 +76,11 @@ struct rpc_call_private {
char nettype[NETIDLEN]; /* Network type */
};
static struct rpc_call_private *rpc_call_private_main;
+static thread_key_t rpc_call_key;
+static once_t rpc_call_once = ONCE_INITIALIZER;
+static int rpc_call_key_error;
+static void rpc_call_key_init(void);
static void rpc_call_destroy(void *);
static void
@@ -91,6 +95,13 @@ rpc_call_destroy(void *vp)
}
}
+static void
+rpc_call_key_init(void)
+{
+
+ rpc_call_key_error = thr_keycreate(&rpc_call_key, rpc_call_destroy);
+}
+
/*
* This is the simplified interface to the client rpc layer.
* The client handle is not destroyed here and is reused for
@@ -112,17 +123,16 @@ rpc_call(host, prognum, versnum, procnum
struct rpc_call_private *rcp = (struct rpc_call_private *) 0;
enum clnt_stat clnt_stat;
struct timeval timeout, tottimeout;
- static thread_key_t rpc_call_key;
int main_thread = 1;
if ((main_thread = thr_main())) {
rcp = rpc_call_private_main;
} else {
- if (rpc_call_key == 0) {
- mutex_lock(&tsd_lock);
- if (rpc_call_key == 0)
- thr_keycreate(&rpc_call_key, rpc_call_destroy);
- mutex_unlock(&tsd_lock);
+ if (thr_once(&rpc_call_once, rpc_call_key_init) != 0 ||
+ rpc_call_key_error != 0) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = rpc_call_key_error;
+ return (rpc_createerr.cf_stat);
}
rcp = (struct rpc_call_private *)thr_getspecific(rpc_call_key);
}
Modified: stable/7/lib/libc/rpc/getnetconfig.c
==============================================================================
--- stable/7/lib/libc/rpc/getnetconfig.c Mon Mar 22 15:52:26 2010 (r205449)
+++ stable/7/lib/libc/rpc/getnetconfig.c Mon Mar 22 15:54:56 2010 (r205450)
@@ -130,21 +130,29 @@ static struct netconfig *dup_ncp(struct
static FILE *nc_file; /* for netconfig db */
-static pthread_mutex_t nc_file_lock = PTHREAD_MUTEX_INITIALIZER;
+static mutex_t nc_file_lock = MUTEX_INITIALIZER;
static struct netconfig_info ni = { 0, 0, NULL, NULL};
-static pthread_mutex_t ni_lock = PTHREAD_MUTEX_INITIALIZER;
+static mutex_t ni_lock = MUTEX_INITIALIZER;
+static thread_key_t nc_key;
+static once_t nc_once = ONCE_INITIALIZER;
+static int nc_key_error;
+
+static void
+nc_key_init(void)
+{
+
+ nc_key_error = thr_keycreate(&nc_key, free);
+}
#define MAXNETCONFIGLINE 1000
static int *
__nc_error()
{
- static pthread_mutex_t nc_lock = PTHREAD_MUTEX_INITIALIZER;
- static thread_key_t nc_key = 0;
static int nc_error = 0;
- int error, *nc_addr;
+ int *nc_addr;
/*
* Use the static `nc_error' if we are the main thread
@@ -153,15 +161,8 @@ __nc_error()
*/
if (thr_main())
return (&nc_error);
- if (nc_key == 0) {
- error = 0;
- mutex_lock(&nc_lock);
- if (nc_key == 0)
- error = thr_keycreate(&nc_key, free);
- mutex_unlock(&nc_lock);
- if (error)
- return (&nc_error);
- }
+ if (thr_once(&nc_once, nc_key_init) != 0 || nc_key_error != 0)
+ return (&nc_error);
if ((nc_addr = (int *)thr_getspecific(nc_key)) == NULL) {
nc_addr = (int *)malloc(sizeof (int));
if (thr_setspecific(nc_key, (void *) nc_addr) != 0) {
Modified: stable/7/lib/libc/rpc/key_call.c
==============================================================================
--- stable/7/lib/libc/rpc/key_call.c Mon Mar 22 15:52:26 2010 (r205449)
+++ stable/7/lib/libc/rpc/key_call.c Mon Mar 22 15:54:56 2010 (r205450)
@@ -279,6 +279,9 @@ struct key_call_private {
uid_t uid; /* user-id at last authorization */
};
static struct key_call_private *key_call_private_main = NULL;
+static thread_key_t key_call_key;
+static once_t key_call_once = ONCE_INITIALIZER;
+static int key_call_key_error;
static void
key_call_destroy(void *vp)
@@ -292,6 +295,13 @@ key_call_destroy(void *vp)
}
}
+static void
+key_call_init(void)
+{
+
+ key_call_key_error = thr_keycreate(&key_call_key, key_call_destroy);
+}
+
/*
* Keep the handle cached. This call may be made quite often.
*/
@@ -307,7 +317,6 @@ int vers;
struct utsname u;
int main_thread;
int fd;
- static thread_key_t key_call_key;
#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */
#define TOTAL_TRIES 5 /* Number of tries */
@@ -315,12 +324,9 @@ int vers;
if ((main_thread = thr_main())) {
kcp = key_call_private_main;
} else {
- if (key_call_key == 0) {
- mutex_lock(&tsd_lock);
- if (key_call_key == 0)
- thr_keycreate(&key_call_key, key_call_destroy);
- mutex_unlock(&tsd_lock);
- }
+ if (thr_once(&key_call_once, key_call_init) != 0 ||
+ key_call_key_error != 0)
+ return ((CLIENT *) NULL);
kcp = (struct key_call_private *)thr_getspecific(key_call_key);
}
if (kcp == (struct key_call_private *)NULL) {
Modified: stable/7/lib/libc/rpc/mt_misc.c
==============================================================================
--- stable/7/lib/libc/rpc/mt_misc.c Mon Mar 22 15:52:26 2010 (r205449)
+++ stable/7/lib/libc/rpc/mt_misc.c Mon Mar 22 15:54:56 2010 (r205450)
@@ -28,7 +28,6 @@ __FBSDID("$FreeBSD$");
#define proglst_lock __proglst_lock
#define rpcsoc_lock __rpcsoc_lock
#define svcraw_lock __svcraw_lock
-#define tsd_lock __tsd_lock
#define xprtlist_lock __xprtlist_lock
/* protects the services list (svc.c) */
@@ -76,33 +75,33 @@ pthread_mutex_t rpcsoc_lock = PTHREAD_MU
/* svc_raw.c serialization */
pthread_mutex_t svcraw_lock = PTHREAD_MUTEX_INITIALIZER;
-/* protects TSD key creation */
-pthread_mutex_t tsd_lock = PTHREAD_MUTEX_INITIALIZER;
-
/* xprtlist (svc_generic.c) */
pthread_mutex_t xprtlist_lock = PTHREAD_MUTEX_INITIALIZER;
#undef rpc_createerr
struct rpc_createerr rpc_createerr;
+static thread_key_t rce_key;
+static once_t rce_once = ONCE_INITIALIZER;
+static int rce_key_error;
+
+static void
+rce_key_init(void)
+{
+
+ rce_key_error = thr_keycreate(&rce_key, free);
+}
struct rpc_createerr *
__rpc_createerr()
{
- static thread_key_t rce_key = 0;
struct rpc_createerr *rce_addr = 0;
if (thr_main())
return (&rpc_createerr);
- if ((rce_addr =
- (struct rpc_createerr *)thr_getspecific(rce_key)) != 0) {
- mutex_lock(&tsd_lock);
- if (thr_keycreate(&rce_key, free) != 0) {
- mutex_unlock(&tsd_lock);
- return (&rpc_createerr);
- }
- mutex_unlock(&tsd_lock);
- }
+ if (thr_once(&rce_once, rce_key_init) != 0 || rce_key_error != 0)
+ return (&rpc_createerr);
+ rce_addr = (struct rpc_createerr *)thr_getspecific(rce_key);
if (!rce_addr) {
rce_addr = (struct rpc_createerr *)
malloc(sizeof (struct rpc_createerr));
Modified: stable/7/lib/libc/rpc/mt_misc.h
==============================================================================
--- stable/7/lib/libc/rpc/mt_misc.h Mon Mar 22 15:52:26 2010 (r205449)
+++ stable/7/lib/libc/rpc/mt_misc.h Mon Mar 22 15:54:56 2010 (r205450)
@@ -42,7 +42,6 @@
#define proglst_lock __proglst_lock
#define rpcsoc_lock __rpcsoc_lock
#define svcraw_lock __svcraw_lock
-#define tsd_lock __tsd_lock
#define xprtlist_lock __xprtlist_lock
extern pthread_rwlock_t svc_lock;
Modified: stable/7/lib/libc/rpc/rpc_generic.c
==============================================================================
--- stable/7/lib/libc/rpc/rpc_generic.c Mon Mar 22 15:52:26 2010 (r205449)
+++ stable/7/lib/libc/rpc/rpc_generic.c Mon Mar 22 15:54:56 2010 (r205450)
@@ -221,6 +221,18 @@ getnettype(nettype)
return (_rpctypelist[i].type);
}
+static thread_key_t tcp_key, udp_key;
+static once_t keys_once = ONCE_INITIALIZER;
+static int tcp_key_error, udp_key_error;
+
+static void
+keys_init(void)
+{
+
+ tcp_key_error = thr_keycreate(&tcp_key, free);
+ udp_key_error = thr_keycreate(&udp_key, free);
+}
+
/*
* For the given nettype (tcp or udp only), return the first structure found.
* This should be freed by calling freenetconfigent()
@@ -236,25 +248,15 @@ __rpc_getconfip(nettype)
static char *netid_udp_main;
struct netconfig *dummy;
int main_thread;
- static thread_key_t tcp_key, udp_key;
if ((main_thread = thr_main())) {
netid_udp = netid_udp_main;
netid_tcp = netid_tcp_main;
} else {
- if (tcp_key == 0) {
- mutex_lock(&tsd_lock);
- if (tcp_key == 0)
- thr_keycreate(&tcp_key, free);
- mutex_unlock(&tsd_lock);
- }
+ if (thr_once(&keys_once, keys_init) != 0 ||
+ tcp_key_error != 0 || udp_key_error != 0)
+ return (NULL);
netid_tcp = (char *)thr_getspecific(tcp_key);
- if (udp_key == 0) {
- mutex_lock(&tsd_lock);
- if (udp_key == 0)
- thr_keycreate(&udp_key, free);
- mutex_unlock(&tsd_lock);
- }
netid_udp = (char *)thr_getspecific(udp_key);
}
if (!netid_udp && !netid_tcp) {
Modified: stable/7/lib/libc/rpc/rpc_soc.c
==============================================================================
--- stable/7/lib/libc/rpc/rpc_soc.c Mon Mar 22 15:52:26 2010 (r205449)
+++ stable/7/lib/libc/rpc/rpc_soc.c Mon Mar 22 15:54:56 2010 (r205450)
@@ -360,6 +360,14 @@ registerrpc(prognum, versnum, procnum, p
*/
static thread_key_t clnt_broadcast_key;
static resultproc_t clnt_broadcast_result_main;
+static once_t clnt_broadcast_once = ONCE_INITIALIZER;
+
+static void
+clnt_broadcast_key_init(void)
+{
+
+ thr_keycreate(&clnt_broadcast_key, free);
+}
/*
* Need to translate the netbuf address into sockaddr_in address.
@@ -402,12 +410,7 @@ clnt_broadcast(prog, vers, proc, xargs,
if (thr_main())
clnt_broadcast_result_main = eachresult;
else {
- if (clnt_broadcast_key == 0) {
- mutex_lock(&tsd_lock);
- if (clnt_broadcast_key == 0)
- thr_keycreate(&clnt_broadcast_key, free);
- mutex_unlock(&tsd_lock);
- }
+ thr_once(&clnt_broadcast_once, clnt_broadcast_key_init);
thr_setspecific(clnt_broadcast_key, (void *) eachresult);
}
return rpc_broadcast((rpcprog_t)prog, (rpcvers_t)vers,
More information about the svn-src-stable-7
mailing list