summaryrefslogtreecommitdiffstats
path: root/lib/libc/rpc/getnetconfig.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2010-03-10 13:23:25 +0000
committerjhb <jhb@FreeBSD.org>2010-03-10 13:23:25 +0000
commite0724fd324c89b8c46185fe402fd332141ea5bf5 (patch)
treedae7801acd654dfe736481930016ad68270d7757 /lib/libc/rpc/getnetconfig.c
parent42dc39ae95f85b0f1bedbdfa406342f9ac3e4fcc (diff)
downloadFreeBSD-src-e0724fd324c89b8c46185fe402fd332141ea5bf5.zip
FreeBSD-src-e0724fd324c89b8c46185fe402fd332141ea5bf5.tar.gz
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. PR: threads/144558 Reported by: Sam Robb samrobb of averesystems com (key leak) MFC after: 1 week
Diffstat (limited to 'lib/libc/rpc/getnetconfig.c')
-rw-r--r--lib/libc/rpc/getnetconfig.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/lib/libc/rpc/getnetconfig.c b/lib/libc/rpc/getnetconfig.c
index e5db51a..1310e36 100644
--- a/lib/libc/rpc/getnetconfig.c
+++ b/lib/libc/rpc/getnetconfig.c
@@ -130,21 +130,29 @@ static struct netconfig *dup_ncp(struct netconfig *);
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) {
OpenPOWER on IntegriCloud