summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorraf <none@none>2007-03-20 17:29:57 -0700
committerraf <none@none>2007-03-20 17:29:57 -0700
commitcb6207858a9fcc2feaee22e626912fba281ac969 (patch)
tree9e84b682e42e9c8dcd013b29690be6905e45841d
parentd7306b64c847d897abb9ece8624fca9cf28d358f (diff)
downloadillumos-joyent-cb6207858a9fcc2feaee22e626912fba281ac969.tar.gz
PSARC 2007/129 thr_keycreate_once
6513516 double checked locking code needs a memory barrier
-rw-r--r--usr/src/cmd/dcs/sparc/sun4u/dcs_ses.c35
-rw-r--r--usr/src/cmd/nscd/nscd_switch.c77
-rw-r--r--usr/src/cmd/sgs/libelf/Makefile.targ4
-rw-r--r--usr/src/cmd/sgs/libelf/common/error.c108
-rw-r--r--usr/src/head/pthread.h17
-rw-r--r--usr/src/head/thread.h17
-rw-r--r--usr/src/lib/common/inc/c_synonyms.h2
-rw-r--r--usr/src/lib/libc/inc/libc.h1
-rw-r--r--usr/src/lib/libc/inc/mtlib.h3
-rw-r--r--usr/src/lib/libc/inc/priv_private.h7
-rw-r--r--usr/src/lib/libc/inc/synonyms.h2
-rw-r--r--usr/src/lib/libc/inc/thr_uberdata.h6
-rw-r--r--usr/src/lib/libc/port/gen/crypt.c9
-rw-r--r--usr/src/lib/libc/port/gen/getauxv.c33
-rw-r--r--usr/src/lib/libc/port/gen/getenv.c44
-rw-r--r--usr/src/lib/libc/port/gen/nss_common.c38
-rw-r--r--usr/src/lib/libc/port/gen/nss_dbdefs.c6
-rw-r--r--usr/src/lib/libc/port/gen/privlib.c85
-rw-r--r--usr/src/lib/libc/port/gen/tsdalloc.c26
-rw-r--r--usr/src/lib/libc/port/mapfile-vers4
-rw-r--r--usr/src/lib/libc/port/threads/pthread.c4
-rw-r--r--usr/src/lib/libc/port/threads/rtsched.c4
-rw-r--r--usr/src/lib/libc/port/threads/tdb_agent.c12
-rw-r--r--usr/src/lib/libc/port/threads/tsd.c49
-rw-r--r--usr/src/lib/libcrypt/common/des_crypt.c40
-rw-r--r--usr/src/lib/libexacct/common/exacct_ops.c30
-rw-r--r--usr/src/lib/libgen/common/bgets.c36
-rw-r--r--usr/src/lib/libgen/common/bufsplit.c39
-rw-r--r--usr/src/lib/libgen/common/pathfind.c38
-rw-r--r--usr/src/lib/libgen/common/reg_compile.c38
-rw-r--r--usr/src/lib/libgen/common/reg_step.c38
-rw-r--r--usr/src/lib/libnsl/common/common.c27
-rw-r--r--usr/src/lib/libnsl/netdir/netdir.c11
-rw-r--r--usr/src/lib/libnsl/netselect/netselect.c6
-rw-r--r--usr/src/lib/libnsl/nis/gen/nis_callback.c9
-rw-r--r--usr/src/lib/libnsl/nis/gen/nis_groups.c9
-rw-r--r--usr/src/lib/libnsl/nis/gen/nis_perror.c12
-rw-r--r--usr/src/lib/libnsl/nis/gen/nis_subr.c10
-rw-r--r--usr/src/lib/libnsl/nsl/_errlst.c15
-rw-r--r--usr/src/lib/libnsl/rpc/clnt_perror.c10
-rw-r--r--usr/src/lib/libnsl/rpc/clnt_simple.c9
-rw-r--r--usr/src/lib/libnsl/rpc/clnt_vc.c5
-rw-r--r--usr/src/lib/libnsl/rpc/inet_ntoa.c9
-rw-r--r--usr/src/lib/libnsl/rpc/key_call.c14
-rw-r--r--usr/src/lib/libnsl/rpc/mt_misc.c15
-rw-r--r--usr/src/lib/libnsl/rpc/rpc_generic.c33
-rw-r--r--usr/src/lib/libnsl/rpc/rpc_soc.c15
-rw-r--r--usr/src/lib/libnsl/rpc/rpcsec_gss_if.c56
-rw-r--r--usr/src/lib/libpool/common/pool.c23
-rw-r--r--usr/src/lib/libproc/common/Pcontrol.c4
-rw-r--r--usr/src/lib/libresolv2/common/irs/gai_strerror.c20
-rw-r--r--usr/src/lib/libresolv2/common/irs/irs_data.c21
-rw-r--r--usr/src/lib/libsasl/lib/common.c20
-rw-r--r--usr/src/lib/libscf/common/error.c64
-rw-r--r--usr/src/lib/libsocket/inet/ether_addr.c24
-rw-r--r--usr/src/lib/libtnfprobe/probe_cntl.c41
-rw-r--r--usr/src/lib/libuutil/common/uu_misc.c53
-rw-r--r--usr/src/lib/rpcsec_gss/rpcsec_gss.c58
58 files changed, 697 insertions, 748 deletions
diff --git a/usr/src/cmd/dcs/sparc/sun4u/dcs_ses.c b/usr/src/cmd/dcs/sparc/sun4u/dcs_ses.c
index 6080fda9e2..e70d76f996 100644
--- a/usr/src/cmd/dcs/sparc/sun4u/dcs_ses.c
+++ b/usr/src/cmd/dcs/sparc/sun4u/dcs_ses.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,9 +18,10 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -59,6 +59,7 @@
#ifdef DCS_MULTI_THREAD
#include <thread.h>
+#include <pthread.h>
#else /* DCS_MULTI_THREAD */
#include <sys/types.h>
#include <sys/wait.h>
@@ -96,8 +97,7 @@ static void ses_thr_exit(void);
* session information.
*/
#ifdef DCS_MULTI_THREAD
-thread_key_t ses_key;
-static int thr_key_created = 0;
+thread_key_t ses_key = THR_ONCE_KEY;
#else /* DCS_MULTI_THREAD */
session_t *ses;
#endif /* DCS_MULTI_THREAD */
@@ -499,13 +499,7 @@ curr_ses(void)
{
#ifdef DCS_MULTI_THREAD
- session_t *sp;
- int thr_err;
-
-
- thr_err = thr_getspecific(ses_key, (void **)&sp);
-
- return ((thr_err) ? NULL : sp);
+ return (pthread_getspecific(ses_key));
#else /* DCS_MULTI_THREAD */
@@ -777,16 +771,9 @@ ses_alloc(void)
int thr_err;
-
- if (!thr_key_created) {
- thr_err = thr_keycreate(&ses_key, NULL);
-
- if (thr_err) {
- return (-1);
- }
-
- thr_key_created = 1;
- }
+ thr_err = thr_keycreate_once(&ses_key, NULL);
+ if (thr_err)
+ return (-1);
#endif /* DCS_MULTI_THREAD */
diff --git a/usr/src/cmd/nscd/nscd_switch.c b/usr/src/cmd/nscd/nscd_switch.c
index ee8c305bfc..c865cef386 100644
--- a/usr/src/cmd/nscd/nscd_switch.c
+++ b/usr/src/cmd/nscd/nscd_switch.c
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,6 +30,7 @@
#include <assert.h>
#include <unistd.h>
#include <string.h>
+#include <pthread.h>
#include <dlfcn.h>
#include <nss_dbdefs.h>
#include <exec_attr.h>
@@ -86,9 +88,7 @@ retry_test(nss_status_t res, int n, struct __nsw_lookup_v1 *lkp)
return (0);
}
-static thread_key_t loopback_key;
-static mutex_t loopback_key_lock = DEFAULTMUTEX;
-static int loopback_key_created = 0;
+static thread_key_t loopback_key = THR_ONCE_KEY;
typedef struct lb_key {
int srci;
int dbi;
@@ -99,25 +99,12 @@ typedef struct lb_key {
static int
set_loopback_key(lb_key_t *key) {
- int rc = 0;
- lb_key_t *k;
+ int rc;
- if (!loopback_key_created) {
- (void) mutex_lock(&loopback_key_lock);
- if (!loopback_key_created) {
- if ((rc = thr_keycreate(&loopback_key,
- NULL)) == 0)
- loopback_key_created = 1;
- }
- (void) mutex_unlock(&loopback_key_lock);
- }
- if (rc == 0) {
- /* set key if not already set */
- if (thr_getspecific(loopback_key, (void **)&k) == 0 &&
- k == NULL) {
- rc = thr_setspecific(loopback_key, key);
- }
- }
+ rc = thr_keycreate_once(&loopback_key, NULL);
+ /* set key if not already set */
+ if (rc == 0 && pthread_getspecific(loopback_key) == NULL)
+ rc = thr_setspecific(loopback_key, key);
return (rc);
}
@@ -126,21 +113,14 @@ static lb_key_t *
get_loopback_key(void) {
char *me = "get_loopback_key";
- int rc = 0;
lb_key_t *k = NULL;
- if (!loopback_key_created)
- return (NULL);
-
- rc = thr_getspecific(loopback_key, (void **)&k);
+ k = pthread_getspecific(loopback_key);
_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
- (me, "get loopback key rc= %d, key = %p\n", rc, k);
+ (me, "get loopback key, key = %p\n", k);
- if (rc == 0 && k != NULL)
- return (k);
-
- return (NULL);
+ return (k);
}
static void
@@ -148,7 +128,7 @@ clear_loopback_key(lb_key_t *key) {
char *me = "clear_loopback_key";
- if (loopback_key_created && key != 0) {
+ if (loopback_key != THR_ONCE_KEY && key != NULL) {
/*
* key->lb_flagp points to the location of the
* flag, check_flag, in the stack where it was
@@ -163,23 +143,14 @@ clear_loopback_key(lb_key_t *key) {
(me, "key %p cleared\n", key);
}
-static thread_key_t initf_key;
-static mutex_t initf_key_lock = DEFAULTMUTEX;
-static int initf_key_created = 0;
+static thread_key_t initf_key = THR_ONCE_KEY;
static int
set_initf_key(void *pbuf) {
- int rc = 0;
+ int rc;
- if (!initf_key_created) {
- (void) mutex_lock(&initf_key_lock);
- if (!initf_key_created) {
- if ((rc = thr_keycreate(&initf_key, NULL)) == 0)
- initf_key_created = 1;
- }
- (void) mutex_unlock(&initf_key_lock);
- }
+ rc = thr_keycreate_once(&initf_key, NULL);
if (rc == 0)
rc = thr_setspecific(initf_key, pbuf);
@@ -191,20 +162,13 @@ get_initf_key(void) {
char *me = "get_initf_key";
void *pbuf;
- int rc = 0;
- if (!initf_key_created)
- return (NULL);
-
- rc = thr_getspecific(initf_key, (void **)&pbuf);
+ pbuf = pthread_getspecific(initf_key);
_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
- (me, "got initf pbuf rc= %d, key = %p\n", rc, pbuf);
-
- if (rc == 0 && pbuf != NULL)
- return (pbuf);
+ (me, "got initf pbuf, key = %p\n", pbuf);
- return (NULL);
+ return (pbuf);
}
static void
@@ -212,8 +176,7 @@ clear_initf_key(void) {
char *me = "clear_initf_key";
- if (initf_key_created)
- (void) thr_setspecific(initf_key, NULL);
+ (void) thr_setspecific(initf_key, NULL);
_NSCD_LOG(NSCD_LOG_SWITCH_ENGINE, NSCD_LOG_LEVEL_DEBUG)
(me, "initf pbuf cleared\n");
diff --git a/usr/src/cmd/sgs/libelf/Makefile.targ b/usr/src/cmd/sgs/libelf/Makefile.targ
index a6d140f8a6..d7d29db908 100644
--- a/usr/src/cmd/sgs/libelf/Makefile.targ
+++ b/usr/src/cmd/sgs/libelf/Makefile.targ
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -132,6 +132,8 @@ wlocks/%.ll: ../common/%.c
native: $(SGSPROTO)/$(DYNLIB)
+native := CPPFLAGS += -DNATIVE_BUILD
+
$(SGSPROTO)/$(DYNLIB): \
pics .WAIT $$(PICS)
$(BUILD.SO)
diff --git a/usr/src/cmd/sgs/libelf/common/error.c b/usr/src/cmd/sgs/libelf/common/error.c
index 1147e0a105..5b5a3d4d1b 100644
--- a/usr/src/cmd/sgs/libelf/common/error.c
+++ b/usr/src/cmd/sgs/libelf/common/error.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,14 +30,15 @@
#pragma weak elf_errmsg = _elf_errmsg
#pragma weak elf_errno = _elf_errno
-#include "syn.h"
-#include <thread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <libelf.h>
-#include "msg.h"
-#include "decl.h"
+#include "syn.h"
+#include <thread.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <libelf.h>
+#include "msg.h"
+#include "decl.h"
#define ELFERRSHIFT 16
#define SYSERRMASK 0xffff
@@ -50,15 +51,48 @@
*/
static int _elf_err = 0;
-static mutex_t keylock;
-static mutex_t buflock;
-static thread_key_t errkey;
-static thread_key_t bufkey;
-static int keyonce = 0;
-static int bufonce = 0;
-NOTE(DATA_READABLE_WITHOUT_LOCK(keyonce))
-NOTE(DATA_READABLE_WITHOUT_LOCK(bufonce))
+#if !defined(NATIVE_BUILD)
+
+static thread_key_t errkey = THR_ONCE_KEY;
+static thread_key_t bufkey = THR_ONCE_KEY;
+
+#else /* NATIVE_BUILD */
+
+/*
+ * This code is here to enable the building of a native version
+ * of libelf.so when the build machine has not yet been upgraded
+ * to a version of libc that provides thr_keycreate_once().
+ * It should be deleted when solaris_nevada ships.
+ * The code is not MT-safe in a relaxed memory model.
+ */
+
+static thread_key_t errkey = 0;
+static thread_key_t bufkey = 0;
+int
+thr_keycreate_once(thread_key_t *keyp, void (*destructor)(void *))
+{
+ static mutex_t key_lock = DEFAULTMUTEX;
+ thread_key_t key;
+ int error;
+
+ if (*keyp == 0) {
+ mutex_lock(&key_lock);
+ if (*keyp == 0) {
+ error = thr_keycreate(&key, destructor);
+ if (error) {
+ mutex_unlock(&key_lock);
+ return (error);
+ }
+ *keyp = key;
+ }
+ mutex_unlock(&key_lock);
+ }
+
+ return (0);
+}
+
+#endif /* NATIVE_BUILD */
extern char *_dgettext(const char *, const char *);
@@ -83,31 +117,17 @@ _elf_seterr(Msg lib_err, int sys_err)
return;
}
#endif
- if (keyonce == 0) {
- (void) mutex_lock(&keylock);
- if (keyonce == 0) {
- (void) thr_keycreate(&errkey, 0);
- keyonce++;
- }
- (void) mutex_unlock(&keylock);
- }
-
+ (void) thr_keycreate_once(&errkey, 0);
(void) thr_setspecific(errkey, (void *)encerr);
}
int
_elf_geterr() {
- intptr_t rc;
-
#ifndef __lock_lint
if (thr_main())
return (_elf_err);
#endif
- if (keyonce == 0)
- return (0);
-
- (void) thr_getspecific(errkey, (void **)(&rc));
- return ((int)rc);
+ return ((uintptr_t)pthread_getspecific(errkey));
}
const char *
@@ -138,19 +158,9 @@ elf_errmsg(int err)
*
* Each thread has its own private buffer.
*/
- if (bufonce == 0) {
- (void) mutex_lock(&buflock);
- if (bufonce == 0) {
- if (thr_keycreate(&bufkey, free) != 0) {
- (void) mutex_unlock(&buflock);
- return (MSG_INTL(EBUG_THRDKEY));
- }
- bufonce++;
- }
- (void) mutex_unlock(&buflock);
- }
-
- (void) thr_getspecific(bufkey, (void **)&buffer);
+ if (thr_keycreate_once(&bufkey, free) != 0)
+ return (MSG_INTL(EBUG_THRDKEY));
+ buffer = pthread_getspecific(bufkey);
if (!buffer) {
if ((buffer = malloc(MAXELFERR)) == 0)
diff --git a/usr/src/head/pthread.h b/usr/src/head/pthread.h
index 44ff4e6b4c..c90aceb127 100644
--- a/usr/src/head/pthread.h
+++ b/usr/src/head/pthread.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -130,6 +130,13 @@ extern "C" {
#define PTHREAD_ONCE_DONE 1
#define PTHREAD_ONCE_INIT {0, 0, 0, PTHREAD_ONCE_NOTDONE}
+/*
+ * The key to be created by pthread_key_create_once_np()
+ * must be statically initialized with PTHREAD_ONCE_KEY_NP.
+ * This must be the same as THR_ONCE_KEY in <thread.h>
+ */
+#define PTHREAD_ONCE_KEY_NP (pthread_key_t)(-1)
+
/* barriers */
#define PTHREAD_BARRIER_SERIAL_THREAD -2
@@ -232,6 +239,7 @@ extern int pthread_setcanceltype(int, int *);
extern void pthread_testcancel(void);
extern int pthread_equal(pthread_t, pthread_t);
extern int pthread_key_create(pthread_key_t *, void (*)(void *));
+extern int pthread_key_create_once_np(pthread_key_t *, void (*)(void *));
extern int pthread_key_delete(pthread_key_t);
extern int pthread_setspecific(pthread_key_t, const void *);
extern void *pthread_getspecific(pthread_key_t);
@@ -370,6 +378,7 @@ extern int pthread_setcanceltype();
extern void pthread_testcancel();
extern int pthread_equal();
extern int pthread_key_create();
+extern int pthread_key_create_once_np();
extern int pthread_key_delete();
extern int pthread_setspecific();
extern void *pthread_getspecific();
diff --git a/usr/src/head/thread.h b/usr/src/head/thread.h
index be8e272e21..63f0b7130d 100644
--- a/usr/src/head/thread.h
+++ b/usr/src/head/thread.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -87,6 +87,7 @@ extern void thr_yield(void);
extern int thr_setprio(thread_t, int);
extern int thr_getprio(thread_t, int *);
extern int thr_keycreate(thread_key_t *, void(*)(void *));
+extern int thr_keycreate_once(thread_key_t *, void(*)(void *));
extern int thr_setspecific(thread_key_t, void *);
extern int thr_getspecific(thread_key_t, void **);
extern size_t thr_min_stack(void);
@@ -109,6 +110,7 @@ extern void thr_yield();
extern int thr_setprio();
extern int thr_getprio();
extern int thr_keycreate();
+extern int thr_keycreate_once();
extern int thr_setspecific();
extern int thr_getspecific();
extern size_t thr_min_stack();
@@ -133,6 +135,13 @@ extern size_t thr_min_stack();
#define THR_DAEMON 0x00000100
/*
+ * The key to be created by thr_keycreate_once()
+ * must be statically initialized with THR_ONCE_KEY.
+ * This must be the same as PTHREAD_ONCE_KEY_NP in <pthread.h>
+ */
+#define THR_ONCE_KEY (thread_key_t)(-1)
+
+/*
* The available register states returned by thr_getstate().
*/
#define TRS_VALID 0
diff --git a/usr/src/lib/common/inc/c_synonyms.h b/usr/src/lib/common/inc/c_synonyms.h
index d652cc06c2..807e5f9538 100644
--- a/usr/src/lib/common/inc/c_synonyms.h
+++ b/usr/src/lib/common/inc/c_synonyms.h
@@ -655,6 +655,7 @@ extern "C" {
#define pthread_getspecific _pthread_getspecific
#define pthread_join _pthread_join
#define pthread_key_create _pthread_key_create
+#define pthread_key_create_once_np _pthread_key_create_once_np
#define pthread_key_delete _pthread_key_delete
#define pthread_kill _pthread_kill
#define pthread_mutexattr_destroy _pthread_mutexattr_destroy
@@ -905,6 +906,7 @@ extern "C" {
#define thr_getstate _thr_getstate
#define thr_join _thr_join
#define thr_keycreate _thr_keycreate
+#define thr_keycreate_once _thr_keycreate_once
#define thr_kill _thr_kill
#define thr_main _thr_main
#define thr_min_stack _thr_min_stack
diff --git a/usr/src/lib/libc/inc/libc.h b/usr/src/lib/libc/inc/libc.h
index 65f68f7e2c..020c311eab 100644
--- a/usr/src/lib/libc/inc/libc.h
+++ b/usr/src/lib/libc/inc/libc.h
@@ -80,6 +80,7 @@ extern int _sigwait(sigset_t *);
extern int _thr_getspecific(thread_key_t key, void **valuep);
extern int _thr_setspecific(unsigned int key, void *value);
extern int _thr_keycreate(thread_key_t *pkey, void (*destructor)(void *));
+extern int _thr_keycreate_once(thread_key_t *pkey, void (*destructor)(void *));
extern void *_pthread_getspecific(thread_key_t);
extern int _pollsys(struct pollfd *, nfds_t, const timespec_t *,
const sigset_t *);
diff --git a/usr/src/lib/libc/inc/mtlib.h b/usr/src/lib/libc/inc/mtlib.h
index 629b61ee9b..5d3fbf1451 100644
--- a/usr/src/lib/libc/inc/mtlib.h
+++ b/usr/src/lib/libc/inc/mtlib.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -104,6 +104,7 @@ extern int _thr_kill(thread_t, int);
extern int _thr_create(void *, size_t, void *(*)(void *), void *, long,
thread_t *);
extern int _thr_keycreate(thread_key_t *, void (*)(void *));
+extern int _thr_keycreate_once(thread_key_t *, void (*)(void *));
extern int _thr_setspecific(thread_key_t, void *);
extern int _thr_getspecific(thread_key_t, void **);
extern void *_pthread_getspecific(thread_key_t);
diff --git a/usr/src/lib/libc/inc/priv_private.h b/usr/src/lib/libc/inc/priv_private.h
index 573a3272c8..e33d22dc03 100644
--- a/usr/src/lib/libc/inc/priv_private.h
+++ b/usr/src/lib/libc/inc/priv_private.h
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -40,8 +41,8 @@
extern "C" {
#endif
-#define LOADPRIVDATA(d) if ((d = privdata) == NULL) d = __priv_getdata()
-#define GETPRIVDATA() (privdata == NULL ? __priv_getdata() : privdata)
+#define LOADPRIVDATA(d) d = __priv_getdata()
+#define GETPRIVDATA() __priv_getdata()
#define LOCKPRIVDATA() { \
/* Data already allocated */ \
(void) lock_data(); \
diff --git a/usr/src/lib/libc/inc/synonyms.h b/usr/src/lib/libc/inc/synonyms.h
index 209d7f6063..b6782b3a59 100644
--- a/usr/src/lib/libc/inc/synonyms.h
+++ b/usr/src/lib/libc/inc/synonyms.h
@@ -762,6 +762,7 @@ extern "C" {
#define pthread_getspecific _pthread_getspecific
#define pthread_join _pthread_join
#define pthread_key_create _pthread_key_create
+#define pthread_key_create_once_np _pthread_key_create_once_np
#define pthread_key_delete _pthread_key_delete
#define pthread_kill _pthread_kill
#define pthread_mutexattr_destroy _pthread_mutexattr_destroy
@@ -1038,6 +1039,7 @@ extern "C" {
#define thr_getstate _thr_getstate
#define thr_join _thr_join
#define thr_keycreate _thr_keycreate
+#define thr_keycreate_once _thr_keycreate_once
#define thr_kill _thr_kill
#define thr_main _thr_main
#define thr_min_stack _thr_min_stack
diff --git a/usr/src/lib/libc/inc/thr_uberdata.h b/usr/src/lib/libc/inc/thr_uberdata.h
index c03fb3fdcc..4b00040fcf 100644
--- a/usr/src/lib/libc/inc/thr_uberdata.h
+++ b/usr/src/lib/libc/inc/thr_uberdata.h
@@ -1289,6 +1289,11 @@ extern int __rwlock_init(rwlock_t *, int, void *);
extern int rw_read_is_held(rwlock_t *);
extern int rw_write_is_held(rwlock_t *);
+extern void _membar_enter(void);
+extern void _membar_exit(void);
+extern void _membar_producer(void);
+extern void _membar_consumer(void);
+
extern int _thr_continue(thread_t);
extern int _thr_create(void *, size_t, void *(*)(void *), void *, long,
thread_t *);
@@ -1298,6 +1303,7 @@ extern int _thr_getprio(thread_t, int *);
extern int _thr_getspecific(thread_key_t, void **);
extern int _thr_join(thread_t, thread_t *, void **);
extern int _thr_keycreate(thread_key_t *, PFrV);
+extern int _thr_keycreate_once(thread_key_t *, PFrV);
extern int _thr_key_delete(thread_key_t);
extern int _thr_main(void);
extern thread_t _thr_self(void);
diff --git a/usr/src/lib/libc/port/gen/crypt.c b/usr/src/lib/libc/port/gen/crypt.c
index 52286d4822..ee77dea287 100644
--- a/usr/src/lib/libc/port/gen/crypt.c
+++ b/usr/src/lib/libc/port/gen/crypt.c
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,6 +47,7 @@
#include <fcntl.h>
#include <syslog.h>
#include <unistd.h>
+#include <atomic.h>
#include <crypt.h>
#include <libc.h>
@@ -903,8 +905,10 @@ allocate_KS(void)
int failed;
int assigned;
- if (KS != NULL) /* already allocated */
+ if (KS != NULL) { /* already allocated */
+ membar_consumer();
return (0);
+ }
ks = calloc(16, 48 * sizeof (char));
failed = 0;
@@ -913,6 +917,7 @@ allocate_KS(void)
assigned = 0;
} else {
assigned = 1;
+ membar_producer();
if ((KS = ks) == NULL) /* calloc() failed */
failed = 1;
}
diff --git a/usr/src/lib/libc/port/gen/getauxv.c b/usr/src/lib/libc/port/gen/getauxv.c
index c32fefdfb6..270c21f955 100644
--- a/usr/src/lib/libc/port/gen/getauxv.c
+++ b/usr/src/lib/libc/port/gen/getauxv.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,6 +37,7 @@
#include <mtlib.h>
#include <thread.h>
#include <synch.h>
+#include <atomic.h>
static mutex_t auxlock = DEFAULTMUTEX;
@@ -57,34 +57,37 @@ _getaux(int type)
* passed to the process at exec(2). Only do this once.
*/
if (auxb == NULL) {
- struct stat statb;
- int fd;
-
lmutex_lock(&auxlock);
-
if (auxb == NULL) {
+ struct stat statb;
+ auxv_t *buf = NULL;
+ int fd;
+
if ((fd = open("/proc/self/auxv", O_RDONLY)) != -1 &&
fstat(fd, &statb) != -1)
- auxb = libc_malloc(
+ buf = libc_malloc(
statb.st_size + sizeof (auxv_t));
- if (auxb != NULL) {
- i = read(fd, auxb, statb.st_size);
+ if (buf != NULL) {
+ i = read(fd, buf, statb.st_size);
if (i != -1) {
nauxv = i / sizeof (auxv_t);
- auxb[nauxv].a_type = AT_NULL;
+ buf[nauxv].a_type = AT_NULL;
} else {
- libc_free(auxb);
- auxb = NULL;
+ libc_free(buf);
+ buf = NULL;
}
}
if (fd != -1)
(void) close(fd);
- }
+ membar_producer();
+ auxb = buf;
+ }
lmutex_unlock(&auxlock);
}
+ membar_consumer();
/*
* Scan the auxiliary entries looking for the required type.
diff --git a/usr/src/lib/libc/port/gen/getenv.c b/usr/src/lib/libc/port/gen/getenv.c
index f5bc6d7290..6329a048d8 100644
--- a/usr/src/lib/libc/port/gen/getenv.c
+++ b/usr/src/lib/libc/port/gen/getenv.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -131,26 +131,29 @@ envsize(const char **e)
static void
initenv()
{
- lmutex_lock(&update_lock);
if ((my_environ != environ) || !initenv_done) {
- if (!initenv_done) {
- /* Call the NLSPATH janitor in. */
- clean_env();
+ lmutex_lock(&update_lock);
+ if ((my_environ != environ) || !initenv_done) {
+ if (!initenv_done) {
+ /* Call the NLSPATH janitor in. */
+ clean_env();
- /* Pacify leak detectors in normal operation. */
- orig_environ = environ;
+ /* Pacify leak detectors in normal operation. */
+ orig_environ = environ;
#ifdef __lint
- my_environ = orig_environ;
+ my_environ = orig_environ;
#endif
+ }
+ my_environ = environ;
+ environ_base = my_environ;
+ environ_size = envsize(environ_base);
+ membar_producer();
initenv_done = 1;
}
-
- my_environ = environ;
- environ_base = my_environ;
- environ_size = envsize(environ_base);
+ lmutex_unlock(&update_lock);
}
- lmutex_unlock(&update_lock);
+ membar_consumer();
}
/*
@@ -220,8 +223,7 @@ addtoenv(char *string, int overwrite)
int new_size;
int old_gen;
- if ((my_environ != environ) || !initenv_done)
- initenv();
+ initenv();
lmutex_lock(&update_lock);
@@ -419,8 +421,7 @@ unsetenv(const char *name)
return (-1);
}
- if ((my_environ != environ) || !initenv_done)
- initenv();
+ initenv();
lmutex_lock(&update_lock);
@@ -455,8 +456,7 @@ getenv(const char *name)
{
char *value;
- if (!initenv_done)
- initenv();
+ initenv();
if (findenv(environ, name, 1, &value) != NULL)
return (value);
diff --git a/usr/src/lib/libc/port/gen/nss_common.c b/usr/src/lib/libc/port/gen/nss_common.c
index 2f4349770f..d21f635d42 100644
--- a/usr/src/lib/libc/port/gen/nss_common.c
+++ b/usr/src/lib/libc/port/gen/nss_common.c
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,6 +39,7 @@
#include "synonyms.h"
#include <mtlib.h>
#include <dlfcn.h>
+#include <atomic.h>
#define __NSS_PRIVATE_INTERFACE
#include "nsswitch_priv.h"
@@ -252,7 +254,7 @@ typedef struct nss_cfglist {
#define NSS_CFG_INCR 16
-static nss_cfglist_t *nss_cfg = (nss_cfglist_t *)NULL;
+static nss_cfglist_t *nss_cfg = NULL;
static int nss_cfgcount = 0;
static int nss_cfgmax = 0;
static mutex_t nss_cfglock = DEFAULTMUTEX;
@@ -303,39 +305,47 @@ nss_cfgcn_cmp(const char *cfgname, const char *compname)
static int
nss_cfg_init()
{
+ nss_cfglist_t *cfg;
int i;
/* First time caller? */
- if (nss_cfg != NULL)
+ if (nss_cfg != NULL) {
+ membar_consumer();
return (0);
+ }
/* Initialize internal tables */
lmutex_lock(&nss_cfglock);
if (nss_cfg != NULL) {
lmutex_unlock(&nss_cfglock);
+ membar_consumer();
return (0);
}
- nss_cfg = (nss_cfglist_t *)libc_malloc(NSS_CFG_INCR *
- sizeof (nss_cfglist_t));
- if (nss_cfg == (nss_cfglist_t *)NULL) {
+ cfg = libc_malloc(NSS_CFG_INCR * sizeof (nss_cfglist_t));
+ if (cfg == NULL) {
errno = ENOMEM;
lmutex_unlock(&nss_cfglock);
return (-1);
}
- nss_cfgmax = NSS_CFG_INCR;
- for (i = 0; i < nss_cfgmax; i++) {
- nss_cfg[i].list = (nss_cfgparam_t *)libc_malloc(NSS_CFG_INCR *
- sizeof (nss_cfgparam_t));
- if (nss_cfg[i].list == (nss_cfgparam_t *)NULL) {
+ for (i = 0; i < NSS_CFG_INCR; i++) {
+ cfg[i].list = libc_malloc(
+ NSS_CFG_INCR * sizeof (nss_cfgparam_t));
+ if (cfg[i].list == NULL) {
+ while (--i >= 0)
+ libc_free(cfg[i].list);
+ libc_free(cfg);
errno = ENOMEM;
lmutex_unlock(&nss_cfglock);
return (-1);
}
- nss_cfg[i].max = NSS_CFG_INCR;
+ cfg[i].max = NSS_CFG_INCR;
}
+ nss_cfgmax = NSS_CFG_INCR;
+ membar_producer();
+ nss_cfg = cfg;
+ lmutex_unlock(&nss_cfglock);
/* Initialize Policy Engine values */
- lmutex_unlock(&nss_cfglock);
if (nss_cfg_policy_init() < 0) {
return (-1);
}
@@ -352,7 +362,7 @@ nss_cfgcomp_get(char *name, int add)
size_t nsize;
/* Make sure system is init'd */
- if (nss_cfg == NULL && nss_cfg_init() < 0)
+ if (nss_cfg_init() < 0)
return ((nss_cfglist_t *)NULL);
/* and check component:name validity */
diff --git a/usr/src/lib/libc/port/gen/nss_dbdefs.c b/usr/src/lib/libc/port/gen/nss_dbdefs.c
index 61a2bbf6dd..f22276c769 100644
--- a/usr/src/lib/libc/port/gen/nss_dbdefs.c
+++ b/usr/src/lib/libc/port/gen/nss_dbdefs.c
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,6 +37,7 @@
#include <dlfcn.h>
#include <link.h>
#include <thread.h>
+#include <atomic.h>
/* headers for key2str/str2key routines */
#include <sys/ethernet.h>
#include <exec_attr.h>
@@ -319,10 +321,12 @@ nss_dbop_search(const char *name, uint32_t dbop)
}
getXbyYdbopHASH[hval] = i | DBOP_HASH_TAG;
}
+ membar_producer();
getXbyYdbop_hashed = 1;
}
lmutex_unlock(&getXbydbop_hash_lock);
}
+ membar_consumer();
cp = name;
hval = 0;
while (*cp) {
diff --git a/usr/src/lib/libc/port/gen/privlib.c b/usr/src/lib/libc/port/gen/privlib.c
index 76586f514e..f7d289aa25 100644
--- a/usr/src/lib/libc/port/gen/privlib.c
+++ b/usr/src/lib/libc/port/gen/privlib.c
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -62,6 +63,7 @@
#include <strings.h>
#include <synch.h>
#include <alloca.h>
+#include <atomic.h>
#include <sys/ucred.h>
#include <sys/procfs.h>
#include <sys/param.h>
@@ -233,7 +235,7 @@ __priv_free_info(priv_data_t *d)
int
lock_data(void)
{
- if (privdata == NULL && __priv_getdata() == NULL)
+ if (__priv_getdata() == NULL)
return (-1);
lmutex_lock(&pd_lock);
@@ -310,54 +312,59 @@ static priv_set_t *__priv_allocset(priv_data_t *);
priv_data_t *
__priv_getdata(void)
{
- lmutex_lock(&pd_lock);
if (privdata == NULL) {
- priv_data_t *tmp;
- priv_impl_info_t *ip;
- size_t size = sizeof (priv_impl_info_t) + 2048;
- size_t realsize;
- priv_impl_info_t *aip = alloca(size);
-
- if (getprivinfo(aip, size) != 0)
- goto out;
+ lmutex_lock(&pd_lock);
+ if (privdata == NULL) {
+ priv_data_t *tmp;
+ priv_impl_info_t *ip;
+ size_t size = sizeof (priv_impl_info_t) + 2048;
+ size_t realsize;
+ priv_impl_info_t *aip = alloca(size);
+
+ if (getprivinfo(aip, size) != 0)
+ goto out;
- realsize = PRIV_IMPL_INFO_SIZE(aip);
+ realsize = PRIV_IMPL_INFO_SIZE(aip);
- ip = libc_malloc(realsize);
+ ip = libc_malloc(realsize);
- if (ip == NULL)
- goto out;
+ if (ip == NULL)
+ goto out;
- if (realsize <= size) {
- (void) memcpy(ip, aip, realsize);
- } else if (getprivinfo(ip, realsize) != 0) {
- libc_free(ip);
- goto out;
- }
+ if (realsize <= size) {
+ (void) memcpy(ip, aip, realsize);
+ } else if (getprivinfo(ip, realsize) != 0) {
+ libc_free(ip);
+ goto out;
+ }
- if ((tmp = __priv_parse_info(ip)) == NULL) {
- libc_free(ip);
- goto out;
- }
+ if ((tmp = __priv_parse_info(ip)) == NULL) {
+ libc_free(ip);
+ goto out;
+ }
- /* Allocate the zoneset just once, here */
- tmp->pd_zoneset = __priv_allocset(tmp);
- if (tmp->pd_zoneset == NULL)
- goto clean;
+ /* Allocate the zoneset just once, here */
+ tmp->pd_zoneset = __priv_allocset(tmp);
+ if (tmp->pd_zoneset == NULL)
+ goto clean;
- if (zone_getattr(getzoneid(), ZONE_ATTR_PRIVSET,
- tmp->pd_zoneset, tmp->pd_setsize) == tmp->pd_setsize) {
- privdata = tmp;
- goto out;
- }
+ if (zone_getattr(getzoneid(), ZONE_ATTR_PRIVSET,
+ tmp->pd_zoneset, tmp->pd_setsize)
+ == tmp->pd_setsize) {
+ membar_producer();
+ privdata = tmp;
+ goto out;
+ }
- priv_freeset(tmp->pd_zoneset);
+ priv_freeset(tmp->pd_zoneset);
clean:
- __priv_free_info(tmp);
- libc_free(ip);
- }
+ __priv_free_info(tmp);
+ libc_free(ip);
+ }
out:
- lmutex_unlock(&pd_lock);
+ lmutex_unlock(&pd_lock);
+ }
+ membar_consumer();
return (privdata);
}
diff --git a/usr/src/lib/libc/port/gen/tsdalloc.c b/usr/src/lib/libc/port/gen/tsdalloc.c
index c6549402b5..1da9dc01e2 100644
--- a/usr/src/lib/libc/port/gen/tsdalloc.c
+++ b/usr/src/lib/libc/port/gen/tsdalloc.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -65,9 +65,7 @@ _free_tsdbuf(void *ptr)
void *
tsdalloc(__tsd_item_t n, size_t size, pfrv_t destructor)
{
- static int once_key = 0;
- static mutex_t key_lock = DEFAULTMUTEX;
- static thread_key_t key;
+ static thread_key_t key = THR_ONCE_KEY;
tsdent_t *loc;
void *p;
int error;
@@ -77,17 +75,9 @@ tsdalloc(__tsd_item_t n, size_t size, pfrv_t destructor)
return (NULL);
}
- if (once_key == 0) {
- lmutex_lock(&key_lock);
- if (once_key == 0) {
- if ((error = _thr_keycreate(&key, _free_tsdbuf)) != 0) {
- lmutex_unlock(&key_lock);
- errno = error;
- return (NULL);
- }
- once_key = 1;
- }
- lmutex_unlock(&key_lock);
+ if ((error = _thr_keycreate_once(&key, _free_tsdbuf)) != 0) {
+ errno = error;
+ return (NULL);
}
if ((loc = _pthread_getspecific(key)) != NULL) {
diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers
index 0475f99826..7168e3d575 100644
--- a/usr/src/lib/libc/port/mapfile-vers
+++ b/usr/src/lib/libc/port/mapfile-vers
@@ -78,6 +78,7 @@ SUNW_1.23 { # SunOS 5.11 (Solaris 11)
mq_unlink;
nanosleep;
posix_fallocate;
+ pthread_key_create_once_np;
_renameat;
sched_getparam;
sched_get_priority_max;
@@ -104,6 +105,7 @@ SUNW_1.23 { # SunOS 5.11 (Solaris 11)
sigtimedwait;
sigwaitinfo;
strnlen;
+ thr_keycreate_once;
timer_create;
timer_delete;
timer_getoverrun;
@@ -1857,6 +1859,7 @@ SUNWprivate_1.1 {
_pthread_getspecific;
_pthread_join;
_pthread_key_create;
+ _pthread_key_create_once_np;
_pthread_key_delete;
_pthread_kill;
__pthread_min_stack;
@@ -2087,6 +2090,7 @@ SUNWprivate_1.1 {
_thr_getstate;
_thr_join;
_thr_keycreate;
+ _thr_keycreate_once;
_thr_key_delete;
_thr_kill;
_thr_main;
diff --git a/usr/src/lib/libc/port/threads/pthread.c b/usr/src/lib/libc/port/threads/pthread.c
index d8c324a7d9..baaadae7bd 100644
--- a/usr/src/lib/libc/port/threads/pthread.c
+++ b/usr/src/lib/libc/port/threads/pthread.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -145,10 +145,12 @@ _pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
&once->mlock);
(*init_routine)();
pthread_cleanup_pop(0);
+ _membar_producer();
once->once_flag = PTHREAD_ONCE_DONE;
}
(void) _private_mutex_unlock(&once->mlock);
}
+ _membar_consumer();
return (0);
}
diff --git a/usr/src/lib/libc/port/threads/rtsched.c b/usr/src/lib/libc/port/threads/rtsched.c
index a85118dc5c..c76e0b722a 100644
--- a/usr/src/lib/libc/port/threads/rtsched.c
+++ b/usr/src/lib/libc/port/threads/rtsched.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -112,10 +112,12 @@ _validate_rt_prio(int policy, int pri)
lmutex_lock(&prio_lock);
if (!initialized) { /* do this only once */
_init_rt_prio_ranges();
+ _membar_producer();
initialized = 1;
}
lmutex_unlock(&prio_lock);
}
+ _membar_consumer();
switch (policy) {
case SCHED_FIFO:
diff --git a/usr/src/lib/libc/port/threads/tdb_agent.c b/usr/src/lib/libc/port/threads/tdb_agent.c
index 938766fa32..bd9d7cf187 100644
--- a/usr/src/lib/libc/port/threads/tdb_agent.c
+++ b/usr/src/lib/libc/port/threads/tdb_agent.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -217,9 +217,10 @@ initialize_sync_hash()
addr_hash[tdb_addr_hash(&udp->tdb_hash_lock)] =
(uintptr_t)&udp->tdb_hash_lock_stats;
+ tdbp->tdb_register_count = 1;
/* assign to tdb_sync_addr_hash only after fully initialized */
+ _membar_producer();
tdbp->tdb_sync_addr_hash = addr_hash;
- tdbp->tdb_register_count = 1;
lmutex_unlock(&udp->tdb_hash_lock);
}
@@ -269,6 +270,7 @@ tdb_sync_obj_register(void *addr, int *new)
goto out;
}
}
+ _membar_consumer();
sapp = &tdbp->tdb_sync_addr_hash[tdb_addr_hash(addr)];
if (udp->uberflags.uf_tdb_register_sync == REGISTER_SYNC_ON) {
diff --git a/usr/src/lib/libc/port/threads/tsd.c b/usr/src/lib/libc/port/threads/tsd.c
index 11484f6763..ac89be862d 100644
--- a/usr/src/lib/libc/port/threads/tsd.c
+++ b/usr/src/lib/libc/port/threads/tsd.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -128,6 +128,47 @@ _thr_keycreate(thread_key_t *pkey, void (*destructor)(void *))
return (0);
}
+/*
+ * Same as _thr_keycreate(), above, except that the key creation
+ * is performed only once. This relies upon the fact that a key
+ * value of THR_ONCE_KEY is invalid, and requires that the key be
+ * allocated with a value of THR_ONCE_KEY before calling here.
+ * THR_ONCE_KEY and PTHREAD_ONCE_KEY_NP, defined in <thread.h>
+ * and <pthread.h> respectively, must have the same value.
+ * Example:
+ *
+ * static pthread_key_t key = PTHREAD_ONCE_KEY_NP;
+ * ...
+ * pthread_key_create_once_np(&key, destructor);
+ */
+#pragma weak pthread_key_create_once_np = _thr_keycreate_once
+#pragma weak _pthread_key_create_once_np = _thr_keycreate_once
+#pragma weak thr_keycreate_once = _thr_keycreate_once
+int
+_thr_keycreate_once(thread_key_t *keyp, void (*destructor)(void *))
+{
+ static mutex_t key_lock = DEFAULTMUTEX;
+ thread_key_t key;
+ int error;
+
+ if (*keyp == THR_ONCE_KEY) {
+ lmutex_lock(&key_lock);
+ if (*keyp == THR_ONCE_KEY) {
+ error = _thr_keycreate(&key, destructor);
+ if (error) {
+ lmutex_unlock(&key_lock);
+ return (error);
+ }
+ _membar_producer();
+ *keyp = key;
+ }
+ lmutex_unlock(&key_lock);
+ }
+ _membar_consumer();
+
+ return (0);
+}
+
#pragma weak pthread_key_delete = _thr_key_delete
#pragma weak _pthread_key_delete = _thr_key_delete
int
diff --git a/usr/src/lib/libcrypt/common/des_crypt.c b/usr/src/lib/libcrypt/common/des_crypt.c
index 69a7f83152..ceb64a1f98 100644
--- a/usr/src/lib/libcrypt/common/des_crypt.c
+++ b/usr/src/lib/libcrypt/common/des_crypt.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,14 +19,14 @@
* CDDL HEADER END
*/
-/* Copyright (c) 1988 AT&T */
-/* All Rights Reserved */
-
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
#pragma ident "%Z%%M% %I% %E% SMI"
/*LINTLIBRARY*/
@@ -42,7 +41,7 @@
#include <stdlib.h>
#include <thread.h>
-#include <synch.h>
+#include <pthread.h>
#include <sys/types.h>
/* EXPORT DELETE START */
@@ -330,22 +329,18 @@ des_encrypt(char *block, int edflag)
#define IOBUF_SIZE 16
static char *
-_get_iobuf(thread_key_t *key, unsigned size)
+_get_iobuf(thread_key_t *keyp, unsigned size)
{
- char *iobuf = NULL;
-
- if (thr_getspecific(*key, (void **)&iobuf) != 0) {
- if (thr_keycreate(key, free) != 0) {
- return (NULL);
- }
- }
+ char *iobuf;
- if (!iobuf) {
- if (thr_setspecific(*key, (void *)(iobuf = malloc(size)))
- != 0) {
+ if (thr_keycreate_once(keyp, free) != 0)
+ return (NULL);
+ iobuf = pthread_getspecific(*keyp);
+ if (iobuf == NULL) {
+ if (thr_setspecific(*keyp, (iobuf = malloc(size))) != 0) {
if (iobuf)
(void) free(iobuf);
- return (NULL);
+ iobuf = NULL;
}
}
return (iobuf);
@@ -357,8 +352,9 @@ des_crypt(const char *pw, const char *salt)
/* EXPORT DELETE START */
int i, j;
char c, temp;
- static thread_key_t key = 0;
- char block[66], *iobuf = _get_iobuf(&key, IOBUF_SIZE);
+ char block[66];
+ static thread_key_t key = THR_ONCE_KEY;
+ char *iobuf = _get_iobuf(&key, IOBUF_SIZE);
(void) mutex_lock(&lock);
for (i = 0; i < 66; i++)
diff --git a/usr/src/lib/libexacct/common/exacct_ops.c b/usr/src/lib/libexacct/common/exacct_ops.c
index 7a42545b23..63c87a8c05 100644
--- a/usr/src/lib/libexacct/common/exacct_ops.c
+++ b/usr/src/lib/libexacct/common/exacct_ops.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,6 +38,7 @@
#include <stdio.h>
#include <errno.h>
#include <thread.h>
+#include <pthread.h>
#define EXACCT_HDR_STR "exacct"
#define EXACCT_HDR_LEN 7
@@ -45,9 +46,7 @@
#define DEFAULT_ENTRIES 4
#define SYSINFO_BUFSIZE 256
-static mutex_t keylock;
-static thread_key_t errkey;
-static int keyonce = 0;
+static thread_key_t errkey = THR_ONCE_KEY;
static int exacct_errval = 0;
/*
@@ -298,29 +297,18 @@ exacct_seterr(int errval)
exacct_errval = errval;
return;
}
- if (keyonce == 0) {
- (void) mutex_lock(&keylock);
- if (keyonce == 0) {
- (void) thr_keycreate(&errkey, 0);
- keyonce++;
- }
- (void) mutex_unlock(&keylock);
- }
+ (void) thr_keycreate_once(&errkey, 0);
(void) thr_setspecific(errkey, (void *)(intptr_t)errval);
}
int
ea_error(void)
{
- intptr_t errvalp;
-
if (thr_main())
return (exacct_errval);
- if (keyonce == 0)
+ if (errkey == THR_ONCE_KEY)
return (EXR_OK);
-
- (void) thr_getspecific(errkey, (void**)&errvalp);
- return ((int)errvalp);
+ return ((int)(uintptr_t)pthread_getspecific(errkey));
}
/*
diff --git a/usr/src/lib/libgen/common/bgets.c b/usr/src/lib/libgen/common/bgets.c
index befc87c0db..19305b372c 100644
--- a/usr/src/lib/libgen/common/bgets.c
+++ b/usr/src/lib/libgen/common/bgets.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,14 +19,14 @@
* CDDL HEADER END
*/
-/* Copyright (c) 1988 AT&T */
-/* All Rights Reserved */
-
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
#pragma ident "%Z%%M% %I% %E% SMI"
/*
@@ -46,6 +45,7 @@
#include <stdlib.h>
#include <string.h>
#include <thread.h>
+#include <pthread.h>
#define CHARS 256
@@ -57,21 +57,19 @@ static char *stop = NULL;
#ifdef _REENTRANT
static char *
-_get_stop(thread_key_t *key)
+_get_stop(thread_key_t *keyp)
{
- char *str = NULL;
+ char *str;
- if (thr_getspecific(*key, (void **)&str) != 0) {
- if (thr_keycreate(key, free) != 0) {
- return (NULL);
- }
- }
- if (!str) {
- if (thr_setspecific(*key, (void *)(str = calloc(CHARS,
- sizeof (char)))) != 0) {
+ if (thr_keycreate_once(keyp, free) != 0)
+ return (NULL);
+ str = pthread_getspecific(*keyp);
+ if (str == NULL) {
+ str = calloc(CHARS, sizeof (char));
+ if (thr_setspecific(*keyp, str) != 0) {
if (str)
(void) free(str);
- return (NULL);
+ str = NULL;
}
}
return (str);
@@ -85,7 +83,7 @@ bgets(char *buf, size_t count, FILE *fp, char *stopstr)
int c;
size_t i;
#ifdef _REENTRANT
- static thread_key_t key = 0;
+ static thread_key_t key = THR_ONCE_KEY;
char *stop = _get_stop(&key);
#else /* _REENTRANT */
if (! stop)
diff --git a/usr/src/lib/libgen/common/bufsplit.c b/usr/src/lib/libgen/common/bufsplit.c
index ac5a043eac..d1ae2ce68d 100644
--- a/usr/src/lib/libgen/common/bufsplit.c
+++ b/usr/src/lib/libgen/common/bufsplit.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,14 +19,14 @@
* CDDL HEADER END
*/
-/* Copyright (c) 1988 AT&T */
-/* All Rights Reserved */
-
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
#pragma ident "%Z%%M% %I% %E% SMI"
/*
@@ -48,6 +47,7 @@
#include <stdlib.h>
#include <string.h>
#include <thread.h>
+#include <pthread.h>
#ifndef _REENTRANT
static char *bsplitchar = "\t\n"; /* characters that separate fields */
@@ -55,24 +55,23 @@ static char *bsplitchar = "\t\n"; /* characters that separate fields */
#ifdef _REENTRANT
static char **
-_get_bsplitchar(thread_key_t *key)
+_get_bsplitchar(thread_key_t *keyp)
{
- static char **strp = NULL;
static char *init_bsplitchar = "\t\n";
+ char **strp;
- if (thr_getspecific(*key, (void **)&strp) != 0) {
- if (thr_keycreate(key, free) != 0) {
- return (NULL);
- }
- }
- if (!strp) {
- if (thr_setspecific(*key, (void *)(strp = malloc(
- sizeof (char *)))) != 0) {
+ if (thr_keycreate_once(keyp, free) != 0)
+ return (NULL);
+ strp = pthread_getspecific(*keyp);
+ if (strp == NULL) {
+ strp = malloc(sizeof (char *));
+ if (thr_setspecific(*keyp, strp) != 0) {
if (strp)
(void) free(strp);
- return (NULL);
+ strp = NULL;
}
- *strp = init_bsplitchar;
+ if (strp != NULL)
+ *strp = init_bsplitchar;
}
return (strp);
}
@@ -82,7 +81,7 @@ size_t
bufsplit(char *buf, size_t dim, char **array)
{
#ifdef _REENTRANT
- static thread_key_t key = 0;
+ static thread_key_t key = THR_ONCE_KEY;
char **bsplitchar = _get_bsplitchar(&key);
#define bsplitchar (*bsplitchar)
#endif /* _REENTRANT */
diff --git a/usr/src/lib/libgen/common/pathfind.c b/usr/src/lib/libgen/common/pathfind.c
index cd45ebfde6..8a0db847ae 100644
--- a/usr/src/lib/libgen/common/pathfind.c
+++ b/usr/src/lib/libgen/common/pathfind.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,14 +19,14 @@
* CDDL HEADER END
*/
-/* Copyright (c) 1988 AT&T */
-/* All Rights Reserved */
-
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
#pragma ident "%Z%%M% %I% %E% SMI"
#pragma weak pathfind = _pathfind
@@ -41,6 +40,7 @@
#include "gen_synonyms.h"
#ifdef _REENTRANT
#include <thread.h>
+#include <pthread.h>
#endif /* _REENTRANT */
#include <sys/types.h>
#include <libgen.h>
@@ -80,21 +80,19 @@ static int fullck(char *, mode_t, int);
#ifdef _REENTRANT
static char *
-_get_cpath(thread_key_t *key)
+_get_cpath(thread_key_t *keyp)
{
- char *str = NULL;
-
- if (thr_getspecific(*key, (void **)&str) != 0) {
- if (thr_keycreate(key, free) != 0) {
- return (NULL);
- }
- }
- if (!str) {
- if (thr_setspecific(*key, (void *)(str = calloc(PATH_MAX,
- sizeof (char)))) != 0) {
+ char *str;
+
+ if (thr_keycreate_once(keyp, free) != 0)
+ return (NULL);
+ str = pthread_getspecific(*keyp);
+ if (str == NULL) {
+ str = calloc(PATH_MAX, sizeof (char));
+ if (thr_setspecific(*keyp, str) != 0) {
if (str)
(void) free(str);
- return (NULL);
+ str = NULL;
}
}
return (str);
@@ -105,7 +103,7 @@ char *
pathfind(const char *path, const char *name, const char *mode)
{
#ifdef _REENTRANT
- static thread_key_t key = 0;
+ static thread_key_t key = THR_ONCE_KEY;
char *cpath = _get_cpath(&key);
#else /* _REENTRANT */
static char cpath[PATH_MAX];
diff --git a/usr/src/lib/libgen/common/reg_compile.c b/usr/src/lib/libgen/common/reg_compile.c
index b2acb39bba..04dae9861e 100644
--- a/usr/src/lib/libgen/common/reg_compile.c
+++ b/usr/src/lib/libgen/common/reg_compile.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,14 +19,14 @@
* CDDL HEADER END
*/
-/* Copyright (c) 1988 AT&T */
-/* All Rights Reserved */
-
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
#pragma ident "%Z%%M% %I% %E% SMI"
#pragma weak nbra = _nbra
@@ -42,6 +41,7 @@
#include <stdlib.h>
#include <string.h>
#include <thread.h>
+#include <pthread.h>
#include <widec.h> /* Defines multibyte and WCHAR_CSMASK for valid_range(). */
#include "_range.h"
#include "_regexp.h"
@@ -75,24 +75,22 @@ typedef struct _vars_storage {
int nbra, regerrno, reglength;
} vars_storage;
-static thread_key_t key = 0;
+static thread_key_t key = THR_ONCE_KEY;
static vars_storage *
-_get_vars_storage(thread_key_t *key)
+_get_vars_storage(thread_key_t *keyp)
{
- vars_storage *vars = NULL;
-
- if (thr_getspecific(*key, (void **)&vars) != 0) {
- if (thr_keycreate(key, free) != 0) {
- return (NULL);
- }
- }
- if (!vars) {
- if (thr_setspecific(*key, (void *)(vars =
- calloc(1, sizeof (vars_storage)))) != 0) {
+ vars_storage *vars;
+
+ if (thr_keycreate_once(keyp, free) != 0)
+ return (NULL);
+ vars = pthread_getspecific(*keyp);
+ if (vars == NULL) {
+ vars = calloc(1, sizeof (vars_storage));
+ if (thr_setspecific(*keyp, vars) != 0) {
if (vars)
(void) free(vars);
- return (NULL);
+ vars = NULL;
}
}
return (vars);
diff --git a/usr/src/lib/libgen/common/reg_step.c b/usr/src/lib/libgen/common/reg_step.c
index ad46f7f1d2..3e164e8d3d 100644
--- a/usr/src/lib/libgen/common/reg_step.c
+++ b/usr/src/lib/libgen/common/reg_step.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,14 +19,14 @@
* CDDL HEADER END
*/
-/* Copyright (c) 1988 AT&T */
-/* All Rights Reserved */
-
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
#pragma ident "%Z%%M% %I% %E% SMI"
#pragma weak loc1 = _loc1
@@ -46,6 +45,7 @@
#include <string.h>
#include <synch.h>
#include <thread.h>
+#include <pthread.h>
#include <widec.h>
#include "_regexp.h"
@@ -59,7 +59,7 @@ char *braslist[_NBRA] = { (char *)0};
char *braelist[_NBRA] = { (char *)0};
#ifdef _REENTRANT
-static thread_key_t key = 0;
+static thread_key_t key = THR_ONCE_KEY;
typedef struct _vars_storage {
char *loc1, *loc2, *locs;
char *braslist[_NBRA];
@@ -79,21 +79,19 @@ static char *start;
static mutex_t lock = DEFAULTMUTEX;
static vars_storage *
-_get_vars_storage(thread_key_t *key)
+_get_vars_storage(thread_key_t *keyp)
{
- vars_storage *vars = NULL;
-
- if (thr_getspecific(*key, (void **)&vars) != 0) {
- if (thr_keycreate(key, free) != 0) {
- return (NULL);
- }
- }
- if (!vars) {
- if (thr_setspecific(*key, (void *)(vars =
- calloc(1, sizeof (vars_storage)))) != 0) {
+ vars_storage *vars;
+
+ if (thr_keycreate_once(keyp, free) != 0)
+ return (NULL);
+ vars = pthread_getspecific(*keyp);
+ if (vars == NULL) {
+ vars = calloc(1, sizeof (vars_storage));
+ if (thr_setspecific(*keyp, vars) != 0) {
if (vars)
(void) free(vars);
- return (NULL);
+ vars = NULL;
}
}
return (vars);
diff --git a/usr/src/lib/libnsl/common/common.c b/usr/src/lib/libnsl/common/common.c
index 5442fe1ad9..ea9779646b 100644
--- a/usr/src/lib/libnsl/common/common.c
+++ b/usr/src/lib/libnsl/common/common.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,26 +32,14 @@
void *
thr_get_storage(pthread_key_t *keyp, size_t size, void (*destructor)(void *))
{
- extern mutex_t tsd_lock;
- pthread_key_t key;
void *addr;
- if ((key = *keyp) == 0) {
- (void) mutex_lock(&tsd_lock);
- if ((key = *keyp) == 0) {
- if (pthread_key_create(keyp, destructor) != 0) {
- (void) mutex_unlock(&tsd_lock);
- return (NULL);
- }
- key = *keyp;
- }
- (void) mutex_unlock(&tsd_lock);
- }
-
- addr = pthread_getspecific(key);
+ if (pthread_key_create_once_np(keyp, destructor) != 0)
+ return (NULL);
+ addr = pthread_getspecific(*keyp);
if (addr == NULL && size != 0) {
addr = calloc(1, size);
- if (addr != NULL && pthread_setspecific(key, addr) != 0) {
+ if (addr != NULL && pthread_setspecific(*keyp, addr) != 0) {
free(addr);
return (NULL);
}
diff --git a/usr/src/lib/libnsl/netdir/netdir.c b/usr/src/lib/libnsl/netdir/netdir.c
index 53a1590876..7d31f85f42 100644
--- a/usr/src/lib/libnsl/netdir/netdir.c
+++ b/usr/src/lib/libnsl/netdir/netdir.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -102,7 +101,7 @@ int _nderror;
int *
__nderror(void)
{
- static pthread_key_t nderror_key = 0;
+ static pthread_key_t nderror_key = PTHREAD_ONCE_KEY_NP;
int *ret;
if (thr_main())
@@ -746,7 +745,7 @@ error:
char *
netdir_sperror(void)
{
- static pthread_key_t nderrbuf_key = 0;
+ static pthread_key_t nderrbuf_key = PTHREAD_ONCE_KEY_NP;
static char buf_main[NDERR_BUFSZ];
char *str;
char *dlerrstr;
diff --git a/usr/src/lib/libnsl/netselect/netselect.c b/usr/src/lib/libnsl/netselect/netselect.c
index 33128e2101..41dfa4909a 100644
--- a/usr/src/lib/libnsl/netselect/netselect.c
+++ b/usr/src/lib/libnsl/netselect/netselect.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -103,7 +103,7 @@ static int fieldnum = 0; /* "owned" by fgetnetconfig() */
static int *
__nc_error(void)
{
- static pthread_key_t nc_error_key = 0;
+ static pthread_key_t nc_error_key = PTHREAD_ONCE_KEY_NP;
static int nc_error = NC_NOERROR;
int *ret;
@@ -815,7 +815,7 @@ char *
nc_sperror(void)
{
static char buf_main[BUFSIZ];
- static pthread_key_t perror_key;
+ static pthread_key_t perror_key = PTHREAD_ONCE_KEY_NP;
char *retstr = thr_main()?
buf_main :
thr_get_storage(&perror_key, BUFSIZ, free);
diff --git a/usr/src/lib/libnsl/nis/gen/nis_callback.c b/usr/src/lib/libnsl/nis/gen/nis_callback.c
index f213ffa045..81d39485e4 100644
--- a/usr/src/lib/libnsl/nis/gen/nis_callback.c
+++ b/usr/src/lib/libnsl/nis/gen/nis_callback.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -133,7 +132,7 @@ static char *__get_clnt_uaddr(CLIENT *);
static void destroy_cbdata(void *);
-static pthread_key_t cbdata_key;
+static pthread_key_t cbdata_key = PTHREAD_ONCE_KEY_NP;
static struct callback_data __cbdata_main;
/*
diff --git a/usr/src/lib/libnsl/nis/gen/nis_groups.c b/usr/src/lib/libnsl/nis/gen/nis_groups.c
index be63da8cf8..5219a73ef5 100644
--- a/usr/src/lib/libnsl/nis/gen/nis_groups.c
+++ b/usr/src/lib/libnsl/nis/gen/nis_groups.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -647,7 +646,7 @@ cached_group_entry(
/* NOTREACHED */
}
-static pthread_key_t visit_log_key;
+static pthread_key_t visit_log_key = PTHREAD_ONCE_KEY_NP;
struct visit_log {
g_entry *ge_id;
struct visit_log *next;
diff --git a/usr/src/lib/libnsl/nis/gen/nis_perror.c b/usr/src/lib/libnsl/nis/gen/nis_perror.c
index 31a2e95828..24ef504f81 100644
--- a/usr/src/lib/libnsl/nis/gen/nis_perror.c
+++ b/usr/src/lib/libnsl/nis/gen/nis_perror.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,12 +18,9 @@
*
* CDDL HEADER END
*/
-/*
- * nis_perror.c
- */
/*
- * Copyright 1988-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -256,7 +252,7 @@ nis_sperror_r(nis_error stat, char *str, char buf[], int len)
char *
nis_sperror(nis_error stat, char *str)
{
- static pthread_key_t err_buf_key;
+ static pthread_key_t err_buf_key = PTHREAD_ONCE_KEY_NP;
char *err_buf;
#define ERR_BUF_SIZE 128
static char err_buf_main[ERR_BUF_SIZE];
diff --git a/usr/src/lib/libnsl/nis/gen/nis_subr.c b/usr/src/lib/libnsl/nis/gen/nis_subr.c
index 386b780927..7d6c202480 100644
--- a/usr/src/lib/libnsl/nis/gen/nis_subr.c
+++ b/usr/src/lib/libnsl/nis/gen/nis_subr.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -468,7 +468,7 @@ nis_leaf_of_r(
return (buf);
}
-static pthread_key_t buf_key;
+static pthread_key_t buf_key = PTHREAD_ONCE_KEY_NP;
static char buf_main[LN_BUFSIZE];
nis_name
@@ -840,7 +840,7 @@ nis_clone_object(
nis_object *obj, /* The object to clone */
nis_object *dest) /* Use this pointer if non-null */
{
- static pthread_key_t clone_buf_key;
+ static pthread_key_t clone_buf_key = PTHREAD_ONCE_KEY_NP;
static struct nis_sdata clone_buf_main;
struct nis_sdata *clone_buf_ptr;
@@ -2107,7 +2107,7 @@ nis_old_data_r(
char *
nis_old_data(char *s)
{
- static pthread_key_t bs_key;
+ static pthread_key_t bs_key = PTHREAD_ONCE_KEY_NP;
static struct nis_sdata bs_main;
struct nis_sdata *bs_ptr;
@@ -2161,7 +2161,7 @@ nis_data_r(char *s, struct nis_sdata *bs_ptr)
char *
nis_data(char *s)
{
- static pthread_key_t bs_key;
+ static pthread_key_t bs_key = PTHREAD_ONCE_KEY_NP;
static struct nis_sdata bs_main;
struct nis_sdata *bs_ptr;
diff --git a/usr/src/lib/libnsl/nsl/_errlst.c b/usr/src/lib/libnsl/nsl/_errlst.c
index 6f7182c191..8702c01d2d 100644
--- a/usr/src/lib/libnsl/nsl/_errlst.c
+++ b/usr/src/lib/libnsl/nsl/_errlst.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,14 +19,14 @@
* CDDL HEADER END
*/
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
#pragma ident "%Z%%M% %I% %E% SMI"
#include "mt.h"
@@ -129,7 +128,7 @@ char *t_errlist[] = {
int *
__t_errno(void)
{
- static pthread_key_t t_errno_key = 0;
+ static pthread_key_t t_errno_key = PTHREAD_ONCE_KEY_NP;
int *ret;
if (thr_main())
diff --git a/usr/src/lib/libnsl/rpc/clnt_perror.c b/usr/src/lib/libnsl/rpc/clnt_perror.c
index ed78cedd3d..39a132b933 100644
--- a/usr/src/lib/libnsl/rpc/clnt_perror.c
+++ b/usr/src/lib/libnsl/rpc/clnt_perror.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,9 +20,10 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
@@ -63,7 +63,7 @@ __buf(void)
{
char *buf;
static char buf_main[ERRBUFSZ];
- static pthread_key_t perror_key;
+ static pthread_key_t perror_key = PTHREAD_ONCE_KEY_NP;
buf = thr_main()? buf_main :
thr_get_storage(&perror_key, ERRBUFSZ, free);
diff --git a/usr/src/lib/libnsl/rpc/clnt_simple.c b/usr/src/lib/libnsl/rpc/clnt_simple.c
index e060136988..b33e1bb85b 100644
--- a/usr/src/lib/libnsl/rpc/clnt_simple.c
+++ b/usr/src/lib/libnsl/rpc/clnt_simple.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -94,7 +93,7 @@ rpc_call(const char *host, const rpcprog_t prognum, const rpcvers_t versnum,
struct rpc_call_private *rcp;
enum clnt_stat clnt_stat;
struct timeval timeout, tottimeout;
- static pthread_key_t rpc_call_key;
+ static pthread_key_t rpc_call_key = PTHREAD_ONCE_KEY_NP;
char nettype_array[NETIDLEN];
char *nettype = &nettype_array[0];
diff --git a/usr/src/lib/libnsl/rpc/clnt_vc.c b/usr/src/lib/libnsl/rpc/clnt_vc.c
index 42d5246ebe..b831b87712 100644
--- a/usr/src/lib/libnsl/rpc/clnt_vc.c
+++ b/usr/src/lib/libnsl/rpc/clnt_vc.c
@@ -20,9 +20,10 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
@@ -1117,7 +1118,7 @@ clnt_vc_destroy(CLIENT *cl)
static int
read_vc(void *ct_tmp, caddr_t buf, int len)
{
- static pthread_key_t pfdp_key;
+ static pthread_key_t pfdp_key = PTHREAD_ONCE_KEY_NP;
struct pollfd *pfdp;
int npfd; /* total number of pfdp allocated */
struct ct_data *ct = ct_tmp;
diff --git a/usr/src/lib/libnsl/rpc/inet_ntoa.c b/usr/src/lib/libnsl/rpc/inet_ntoa.c
index 9ceaf5cbaa..c800df4384 100644
--- a/usr/src/lib/libnsl/rpc/inet_ntoa.c
+++ b/usr/src/lib/libnsl/rpc/inet_ntoa.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -74,7 +73,7 @@ inet_ntoa(in)
{
char *b;
static char b_main[18];
- static pthread_key_t ntoa_key;
+ static pthread_key_t ntoa_key = PTHREAD_ONCE_KEY_NP;
if (thr_main())
b = b_main;
diff --git a/usr/src/lib/libnsl/rpc/key_call.c b/usr/src/lib/libnsl/rpc/key_call.c
index da5e932f15..27e2ac4165 100644
--- a/usr/src/lib/libnsl/rpc/key_call.c
+++ b/usr/src/lib/libnsl/rpc/key_call.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -786,15 +785,14 @@ key_call_destroy(void *vp)
}
}
-static pthread_key_t key_call_key;
+static pthread_key_t key_call_key = PTHREAD_ONCE_KEY_NP;
void
_key_call_fini(void)
{
- struct key_call_private *kcp = NULL;
+ struct key_call_private *kcp;
- if (key_call_key &&
- (kcp = pthread_getspecific(key_call_key)) != NULL) {
+ if ((kcp = pthread_getspecific(key_call_key)) != NULL) {
key_call_destroy(kcp);
(void) pthread_setspecific(key_call_key, NULL);
}
diff --git a/usr/src/lib/libnsl/rpc/mt_misc.c b/usr/src/lib/libnsl/rpc/mt_misc.c
index 21e0328461..14bb897359 100644
--- a/usr/src/lib/libnsl/rpc/mt_misc.c
+++ b/usr/src/lib/libnsl/rpc/mt_misc.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -69,7 +68,6 @@ mutex_t portnum_lock; /* protects ``port'' static in bindresvport() */
mutex_t proglst_lock; /* protects proglst list (svc_simple.c) */
mutex_t rpcsoc_lock; /* serializes clnt_com_create() (rpc_soc.c) */
mutex_t svcraw_lock; /* svc_raw.c serialization */
-mutex_t tsd_lock; /* protects TSD key creation */
mutex_t xprtlist_lock; /* xprtlist (svc_generic.c) */
mutex_t serialize_pkey; /* serializes calls to public key routines */
mutex_t svc_thr_mutex; /* protects thread related variables */
@@ -91,7 +89,6 @@ static mutex_t *mutex_table[] = {
&proglst_lock,
&rpcsoc_lock,
&svcraw_lock,
- &tsd_lock,
&xprtlist_lock,
&serialize_pkey,
&svc_thr_mutex,
@@ -162,7 +159,7 @@ struct rpc_createerr rpc_createerr;
struct rpc_createerr *
__rpc_createerr()
{
- static pthread_key_t rce_key = 0;
+ static pthread_key_t rce_key = PTHREAD_ONCE_KEY_NP;
struct rpc_createerr *rce_addr;
if (thr_main())
@@ -182,8 +179,8 @@ struct rpc_err rpc_callerr;
struct rpc_err *
__rpc_callerr(void)
{
- static pthread_key_t rpc_callerr_key = 0;
- struct rpc_err *tsd = 0;
+ static pthread_key_t rpc_callerr_key = PTHREAD_ONCE_KEY_NP;
+ struct rpc_err *tsd;
if (thr_main())
return (&rpc_callerr);
diff --git a/usr/src/lib/libnsl/rpc/rpc_generic.c b/usr/src/lib/libnsl/rpc/rpc_generic.c
index c45f6071c4..65fb2d08a9 100644
--- a/usr/src/lib/libnsl/rpc/rpc_generic.c
+++ b/usr/src/lib/libnsl/rpc/rpc_generic.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -186,31 +185,21 @@ struct netconfig *
__rpc_getconfip(char *nettype)
{
char *netid;
- char *netid_tcp = NULL;
- char *netid_udp = NULL;
- static char *netid_tcp_main;
- static char *netid_udp_main;
- static pthread_key_t tcp_key, udp_key;
+ char *netid_tcp;
+ char *netid_udp;
+ static char *netid_tcp_main = NULL;
+ static char *netid_udp_main = NULL;
+ static pthread_key_t tcp_key = PTHREAD_ONCE_KEY_NP;
+ static pthread_key_t udp_key = PTHREAD_ONCE_KEY_NP;
int main_thread;
- extern mutex_t tsd_lock;
if ((main_thread = thr_main())) {
netid_udp = netid_udp_main;
netid_tcp = netid_tcp_main;
} else {
- if (tcp_key == 0) {
- (void) mutex_lock(&tsd_lock);
- if (tcp_key == 0)
- (void) pthread_key_create(&tcp_key, free);
- (void) mutex_unlock(&tsd_lock);
- }
+ (void) pthread_key_create_once_np(&tcp_key, free);
netid_tcp = pthread_getspecific(tcp_key);
- if (udp_key == 0) {
- (void) mutex_lock(&tsd_lock);
- if (udp_key == 0)
- (void) pthread_key_create(&udp_key, free);
- (void) mutex_unlock(&tsd_lock);
- }
+ (void) pthread_key_create_once_np(&udp_key, free);
netid_udp = pthread_getspecific(udp_key);
}
if (!netid_udp && !netid_tcp) {
diff --git a/usr/src/lib/libnsl/rpc/rpc_soc.c b/usr/src/lib/libnsl/rpc/rpc_soc.c
index 1cb3f56b4e..d6dbe17b7c 100644
--- a/usr/src/lib/libnsl/rpc/rpc_soc.c
+++ b/usr/src/lib/libnsl/rpc/rpc_soc.c
@@ -20,9 +20,10 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
@@ -457,7 +458,7 @@ registerrpc(rpcprog_t prognum, rpcvers_t versnum, rpcproc_t procnum,
* All the following clnt_broadcast stuff is convulated; it supports
* the earlier calling style of the callback function
*/
-static pthread_key_t clnt_broadcast_key;
+static pthread_key_t clnt_broadcast_key = PTHREAD_ONCE_KEY_NP;
static resultproc_t clnt_broadcast_result_main;
/*
@@ -485,18 +486,10 @@ clnt_broadcast(rpcprog_t prog, rpcvers_t vers, rpcproc_t proc, xdrproc_t xargs,
caddr_t argsp, xdrproc_t xresults,
caddr_t resultsp, resultproc_t eachresult)
{
- extern mutex_t tsd_lock;
-
if (thr_main()) {
clnt_broadcast_result_main = eachresult;
} else {
- if (clnt_broadcast_key == 0) {
- (void) mutex_lock(&tsd_lock);
- if (clnt_broadcast_key == 0)
- (void) pthread_key_create(&clnt_broadcast_key,
- NULL);
- (void) mutex_unlock(&tsd_lock);
- }
+ (void) pthread_key_create_once_np(&clnt_broadcast_key, NULL);
(void) pthread_setspecific(clnt_broadcast_key,
(void *)eachresult);
}
diff --git a/usr/src/lib/libnsl/rpc/rpcsec_gss_if.c b/usr/src/lib/libnsl/rpc/rpcsec_gss_if.c
index 8d85db69c7..9700d8b3b7 100644
--- a/usr/src/lib/libnsl/rpc/rpcsec_gss_if.c
+++ b/usr/src/lib/libnsl/rpc/rpcsec_gss_if.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,6 +29,7 @@
#include "mt.h"
#include "rpc_mt.h"
#include <stdio.h>
+#include <atomic.h>
#include <sys/errno.h>
#include <dlfcn.h>
#include <rpc/rpc.h>
@@ -64,13 +64,18 @@ static bool_t initialized = FALSE;
static bool_t
rpcgss_calls_init(void)
{
- void *handle = NULL;
+ void *handle;
bool_t ret = FALSE;
+ if (initialized) {
+ membar_consumer();
+ return (TRUE);
+ }
(void) mutex_lock(&rpcgss_calls_mutex);
if (initialized) {
- ret = TRUE;
- goto done;
+ (void) mutex_unlock(&rpcgss_calls_mutex);
+ membar_consumer();
+ return (TRUE);
}
if ((handle = dlopen(RPCSEC, RTLD_LAZY)) == NULL)
@@ -137,6 +142,7 @@ done:
if (handle != NULL)
(void) dlclose(handle);
}
+ membar_producer();
initialized = ret;
(void) mutex_unlock(&rpcgss_calls_mutex);
return (ret);
@@ -152,7 +158,7 @@ rpc_gss_seccreate(
rpc_gss_options_req_t *options_req, /* requested options */
rpc_gss_options_ret_t *options_ret) /* returned options */
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (NULL);
return ((*calls.rpc_gss_seccreate)(clnt, principal, mechanism,
service_type, qop, options_req, options_ret));
@@ -161,7 +167,7 @@ rpc_gss_seccreate(
bool_t
rpc_gss_set_defaults(AUTH *auth, rpc_gss_service_t service, char *qop)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (FALSE);
return ((*calls.rpc_gss_set_defaults)(auth, service, qop));
}
@@ -174,7 +180,7 @@ rpc_gss_get_principal_name(
char *node,
char *secdomain)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (FALSE);
return ((*calls.rpc_gss_get_principal_name)(principal, mechanism,
user_name, node, secdomain));
@@ -183,7 +189,7 @@ rpc_gss_get_principal_name(
char **
rpc_gss_get_mechanisms(void)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (NULL);
return ((*calls.rpc_gss_get_mechanisms)());
}
@@ -191,7 +197,7 @@ rpc_gss_get_mechanisms(void)
char **
rpc_gss_get_mech_info(char *mechanism, rpc_gss_service_t *service)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (NULL);
return ((*calls.rpc_gss_get_mech_info)(mechanism, service));
}
@@ -199,7 +205,7 @@ rpc_gss_get_mech_info(char *mechanism, rpc_gss_service_t *service)
bool_t
rpc_gss_get_versions(uint_t *vers_hi, uint_t *vers_lo)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (FALSE);
return ((*calls.rpc_gss_get_versions)(vers_hi, vers_lo));
}
@@ -207,7 +213,7 @@ rpc_gss_get_versions(uint_t *vers_hi, uint_t *vers_lo)
bool_t
rpc_gss_is_installed(char *mechanism)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (FALSE);
return ((*calls.rpc_gss_is_installed)(mechanism));
}
@@ -220,7 +226,7 @@ rpc_gss_set_svc_name(
uint_t program,
uint_t version)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (FALSE);
return ((*calls.rpc_gss_set_svc_name)(principal, mechanism, req_time,
program, version));
@@ -229,7 +235,7 @@ rpc_gss_set_svc_name(
bool_t
rpc_gss_set_callback(rpc_gss_callback_t *cb)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (FALSE);
return ((*calls.rpc_gss_set_callback)(cb));
}
@@ -238,7 +244,7 @@ bool_t
rpc_gss_getcred(struct svc_req *req, rpc_gss_rawcred_t **rcred,
rpc_gss_ucred_t **ucred, void **cookie)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (FALSE);
return ((*calls.rpc_gss_getcred)(req, rcred, ucred, cookie));
}
@@ -246,7 +252,7 @@ rpc_gss_getcred(struct svc_req *req, rpc_gss_rawcred_t **rcred,
bool_t
rpc_gss_mech_to_oid(char *mech, rpc_gss_OID *oid)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (FALSE);
return ((*calls.rpc_gss_mech_to_oid)(mech, oid));
}
@@ -254,7 +260,7 @@ rpc_gss_mech_to_oid(char *mech, rpc_gss_OID *oid)
bool_t
rpc_gss_qop_to_num(char *qop, char *mech, uint_t *num)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (FALSE);
return ((*calls.rpc_gss_qop_to_num)(qop, mech, num));
}
@@ -262,7 +268,7 @@ rpc_gss_qop_to_num(char *qop, char *mech, uint_t *num)
enum auth_stat
__svcrpcsec_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (AUTH_FAILED);
return ((*calls.__svcrpcsec_gss)(rqst, msg, no_dispatch));
}
@@ -271,7 +277,7 @@ bool_t
__rpc_gss_wrap(AUTH *auth, char *buf, uint_t buflen, XDR *out_xdrs,
bool_t (*xdr_func)(), caddr_t xdr_ptr)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (FALSE);
return ((*calls.__rpc_gss_wrap)(auth, buf, buflen, out_xdrs,
xdr_func, xdr_ptr));
@@ -281,7 +287,7 @@ bool_t
__rpc_gss_unwrap(AUTH *auth, XDR *in_xdrs, bool_t (*xdr_func)(),
caddr_t xdr_ptr)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (FALSE);
return ((*calls.__rpc_gss_unwrap)(auth, in_xdrs, xdr_func, xdr_ptr));
}
@@ -289,7 +295,7 @@ __rpc_gss_unwrap(AUTH *auth, XDR *in_xdrs, bool_t (*xdr_func)(),
int
rpc_gss_max_data_length(AUTH *rpcgss_handle, int max_tp_unit_len)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (0);
return ((*calls.rpc_gss_max_data_length)(rpcgss_handle,
max_tp_unit_len));
@@ -298,7 +304,7 @@ rpc_gss_max_data_length(AUTH *rpcgss_handle, int max_tp_unit_len)
int
rpc_gss_svc_max_data_length(struct svc_req *req, int max_tp_unit_len)
{
- if (!initialized && !rpcgss_calls_init())
+ if (!rpcgss_calls_init())
return (0);
return ((*calls.rpc_gss_svc_max_data_length)(req, max_tp_unit_len));
}
@@ -306,7 +312,7 @@ rpc_gss_svc_max_data_length(struct svc_req *req, int max_tp_unit_len)
void
rpc_gss_get_error(rpc_gss_error_t *error)
{
- if (!initialized && !rpcgss_calls_init()) {
+ if (!rpcgss_calls_init()) {
error->rpc_gss_error = RPC_GSS_ER_SYSTEMERROR;
error->system_error = ENOTSUP;
return;
diff --git a/usr/src/lib/libpool/common/pool.c b/usr/src/lib/libpool/common/pool.c
index 31e725e439..bcd8c9af28 100644
--- a/usr/src/lib/libpool/common/pool.c
+++ b/usr/src/lib/libpool/common/pool.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <thread.h>
+#include <pthread.h>
#include <synch.h>
#include <unistd.h>
#include <stropts.h>
@@ -112,9 +113,7 @@ const char pool_info_location[] = "/dev/pool";
*/
static const char static_location[] = "/etc/pooladm.conf";
static const char dynamic_location[] = "/dev/poolctl";
-static mutex_t keylock;
-static thread_key_t errkey;
-static int keyonce = 0;
+static thread_key_t errkey = THR_ONCE_KEY;
/*
* libpool error code
@@ -611,14 +610,7 @@ pool_seterror(int errval)
pool_errval = errval;
return;
}
- if (keyonce == 0) {
- (void) mutex_lock(&keylock);
- if (keyonce == 0) {
- (void) thr_keycreate(&errkey, 0);
- keyonce++;
- }
- (void) mutex_unlock(&keylock);
- }
+ (void) thr_keycreate_once(&errkey, 0);
(void) thr_setspecific(errkey, (void *)(intptr_t)errval);
}
@@ -629,14 +621,11 @@ pool_seterror(int errval)
int
pool_error(void)
{
- void *errval;
-
if (thr_main())
return (pool_errval);
- if (keyonce == 0)
+ if (errkey == THR_ONCE_KEY)
return (POE_OK);
- (void) thr_getspecific(errkey, &errval);
- return ((intptr_t)errval);
+ return ((uintptr_t)pthread_getspecific(errkey));
}
/*
diff --git a/usr/src/lib/libproc/common/Pcontrol.c b/usr/src/lib/libproc/common/Pcontrol.c
index e30d5758cb..6cf0c45891 100644
--- a/usr/src/lib/libproc/common/Pcontrol.c
+++ b/usr/src/lib/libproc/common/Pcontrol.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,6 +38,7 @@
#include <dirent.h>
#include <limits.h>
#include <signal.h>
+#include <atomic.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/stat.h>
@@ -125,6 +126,7 @@ set_minfd(void)
fd = 256;
else if ((fd = rlim.rlim_cur / 2) < 3)
fd = 3;
+ membar_producer();
minfd = fd;
}
(void) mutex_unlock(&minfd_lock);
diff --git a/usr/src/lib/libresolv2/common/irs/gai_strerror.c b/usr/src/lib/libresolv2/common/irs/gai_strerror.c
index e9e1131729..a9e249b418 100644
--- a/usr/src/lib/libresolv2/common/irs/gai_strerror.c
+++ b/usr/src/lib/libresolv2/common/irs/gai_strerror.c
@@ -59,9 +59,7 @@ gai_strerror(int ecode) {
#ifndef DO_PTHREADS
static char buf[EAI_BUFSIZE];
#else /* DO_PTHREADS */
- static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t key;
- static int once = 0;
+ static pthread_key_t key = PTHREAD_ONCE_KEY_NP;
char *buf;
#endif
@@ -69,20 +67,8 @@ gai_strerror(int ecode) {
return (gai_errlist[ecode]);
#ifdef DO_PTHREADS
- if (!once) {
- if (pthread_mutex_lock(&lock) != 0)
- goto unknown;
- if (!once) {
- if (pthread_key_create(&key, free) != 0) {
- pthread_mutex_unlock(&lock);
- goto unknown;
- }
- once = 1;
- }
- if (pthread_mutex_unlock(&lock) != 0)
- goto unknown;
- }
-
+ if (pthread_key_create_once_np(&key, free) != 0)
+ goto unknown;
buf = pthread_getspecific(key);
if (buf == NULL) {
buf = malloc(EAI_BUFSIZE);
diff --git a/usr/src/lib/libresolv2/common/irs/irs_data.c b/usr/src/lib/libresolv2/common/irs/irs_data.c
index 5db332a87f..874c25cef8 100644
--- a/usr/src/lib/libresolv2/common/irs/irs_data.c
+++ b/usr/src/lib/libresolv2/common/irs/irs_data.c
@@ -57,10 +57,9 @@ extern struct __res_state _res;
extern int h_errno;
#ifdef DO_PTHREADS
-static pthread_key_t key;
-static int once = 0;
+static pthread_key_t key = PTHREAD_ONCE_KEY_NP;
#else
-static struct net_data *net_data;
+static struct net_data *net_data = NULL;
#endif
void
@@ -126,22 +125,10 @@ net_data_destroy(void *p) {
struct net_data *
net_data_init(const char *conf_file) {
#ifdef DO_PTHREADS
- static pthread_mutex_t keylock = PTHREAD_MUTEX_INITIALIZER;
struct net_data *net_data;
- if (!once) {
- if (pthread_mutex_lock(&keylock) != 0)
- return (NULL);
- if (!once) {
- if (pthread_key_create(&key, net_data_destroy) != 0) {
- pthread_mutex_unlock(&keylock);
- return (NULL);
- }
- once = 1;
- }
- if (pthread_mutex_unlock(&keylock) != 0)
- return (NULL);
- }
+ if (pthread_key_create_once_np(&key, net_data_destroy) != 0)
+ return (NULL);
net_data = pthread_getspecific(key);
#endif
diff --git a/usr/src/lib/libsasl/lib/common.c b/usr/src/lib/libsasl/lib/common.c
index a4b3d896ec..baceb2ae5d 100644
--- a/usr/src/lib/libsasl/lib/common.c
+++ b/usr/src/lib/libsasl/lib/common.c
@@ -1,7 +1,8 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+
#pragma ident "%Z%%M% %I% %E% SMI"
/* common.c - Functions that are common to server and clinet
@@ -92,8 +93,7 @@ static void _sasl_dispose_context(_sasl_global_context_t *ctx);
static int _sasl_getconf(void *context, const char **conf);
#ifdef _INTEGRATED_SOLARIS_
-static int init_thread_set_specific = 0;
-static pthread_key_t errstring_key;
+static pthread_key_t errstring_key = PTHREAD_ONCE_KEY_NP;
#endif /* _INTEGRATED_SOLARIS_ */
#else
static const char build_ident[] = "$Build: libsasl " PACKAGE "-" VERSION " $";
@@ -1110,8 +1110,6 @@ static int sasl_usererr(int saslerr)
static void free_err_tsd(void *key)
{
free(key);
-
- pthread_setspecific(errstring_key, NULL);
}
#endif /* _INTEGRATED_SOLARIS_ */
@@ -1216,21 +1214,13 @@ const char *sasl_errstring(int saslerr,
if (s_utf8 == NULL)
return s;
- if (!init_thread_set_specific) {
- LOCK_MUTEX(&global_mutex);
- if (!init_thread_set_specific) {
- if (pthread_key_create(&errstring_key, free_err_tsd) == 0)
- init_thread_set_specific = 1;
- }
- UNLOCK_MUTEX(&global_mutex);
- }
- if (!init_thread_set_specific) {
+ if (pthread_key_create_once_np(&errstring_key, free_err_tsd) != 0) {
free(s_utf8);
return s;
}
tsd = pthread_getspecific(errstring_key);
- if (tsd == NULL)
+ if (tsd != NULL)
free(tsd);
pthread_setspecific(errstring_key, s_utf8);
diff --git a/usr/src/lib/libscf/common/error.c b/usr/src/lib/libscf/common/error.c
index c0272a7776..c9f285837d 100644
--- a/usr/src/lib/libscf/common/error.c
+++ b/usr/src/lib/libscf/common/error.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -80,36 +80,56 @@ static struct scf_error_info {
((e) >= scf_errors[0].ei_code && \
(e) < scf_errors[SCF_NUM_ERRORS - 1].ei_code + 10)
-static pthread_mutex_t scf_key_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_key_t scf_error_key;
-static volatile int scf_error_key_setup;
-
static scf_error_t _scf_fallback_error = SCF_ERROR_NONE;
+#if defined(PTHREAD_ONCE_KEY_NP)
+
+static pthread_key_t scf_error_key = PTHREAD_ONCE_KEY_NP;
+
int
scf_setup_error(void)
{
- (void) pthread_mutex_lock(&scf_key_lock);
+ return (pthread_key_create_once_np(&scf_error_key, NULL) == 0);
+}
+
+#else /* PTHREAD_ONCE_KEY_NP */
+
+/*
+ * This old code is here to enable the building of a native version
+ * of libscf.so when the build machine has not yet been upgraded
+ * to a version of libc that provides pthread_key_create_once_np().
+ * It should be deleted when solaris_nevada ships.
+ * This code is not MT-safe in a relaxed memory model.
+ */
+
+static pthread_key_t scf_error_key = 0;
+
+int
+scf_setup_error(void)
+{
+ static pthread_mutex_t scf_key_lock = PTHREAD_MUTEX_INITIALIZER;
+ static volatile int scf_error_key_setup = 0;
+
if (scf_error_key_setup == 0) {
- if (pthread_key_create(&scf_error_key, NULL) != 0)
- scf_error_key_setup = -1;
- else
- scf_error_key_setup = 1;
+ (void) pthread_mutex_lock(&scf_key_lock);
+ if (scf_error_key_setup == 0) {
+ if (pthread_key_create(&scf_error_key, NULL) == 0)
+ scf_error_key_setup = 1;
+ }
+ (void) pthread_mutex_unlock(&scf_key_lock);
}
- (void) pthread_mutex_unlock(&scf_key_lock);
return (scf_error_key_setup == 1);
}
+#endif /* PTHREAD_ONCE_KEY_NP */
+
int
scf_set_error(scf_error_t code)
{
assert(LOOKS_VALID(code));
- if (scf_error_key_setup == 0)
- (void) scf_setup_error();
-
- if (scf_error_key_setup > 0)
+ if (scf_setup_error())
(void) pthread_setspecific(scf_error_key, (void *)code);
else
_scf_fallback_error = code;
@@ -121,15 +141,9 @@ scf_error(void)
{
scf_error_t ret;
- if (scf_error_key_setup < 0)
- return (_scf_fallback_error);
-
- if (scf_error_key_setup == 0)
- return (SCF_ERROR_NONE);
-
ret = (scf_error_t)pthread_getspecific(scf_error_key);
if (ret == 0)
- return (SCF_ERROR_NONE);
+ return (_scf_fallback_error);
assert(LOOKS_VALID(ret));
return (ret);
}
diff --git a/usr/src/lib/libsocket/inet/ether_addr.c b/usr/src/lib/libsocket/inet/ether_addr.c
index 44f8979691..12c7a06f70 100644
--- a/usr/src/lib/libsocket/inet/ether_addr.c
+++ b/usr/src/lib/libsocket/inet/ether_addr.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -54,6 +54,7 @@
#include <stdlib.h>
#include <sys/types.h>
#include <thread.h>
+#include <pthread.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
@@ -240,27 +241,16 @@ typedef struct {
static eabuf_t *
ea_buf(void)
{
- static thread_key_t key;
- static int key_once = 0;
- static mutex_t tsd_lock = DEFAULTMUTEX;
+ static thread_key_t key = THR_ONCE_KEY;
static eabuf_t ea_main;
- eabuf_t *eabuf = NULL;
+ eabuf_t *eabuf;
if (thr_main())
return (&ea_main);
- if (key_once == 0) {
- (void) mutex_lock(&tsd_lock);
- if (key_once == 0) {
- if (thr_keycreate(&key, free) != 0) {
- (void) mutex_unlock(&tsd_lock);
- return (NULL);
- }
- key_once = 1;
- }
- (void) mutex_unlock(&tsd_lock);
- }
- (void) thr_getspecific(key, (void **)&eabuf);
+ if (thr_keycreate_once(&key, free) != 0)
+ return (NULL);
+ eabuf = pthread_getspecific(key);
if (eabuf == NULL) {
eabuf = malloc(sizeof (eabuf_t));
(void) thr_setspecific(key, eabuf);
diff --git a/usr/src/lib/libtnfprobe/probe_cntl.c b/usr/src/lib/libtnfprobe/probe_cntl.c
index dd686735b0..4c5f53982f 100644
--- a/usr/src/lib/libtnfprobe/probe_cntl.c
+++ b/usr/src/lib/libtnfprobe/probe_cntl.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -601,8 +601,7 @@ probestart(void * arg)
} /* end probestart */
-static thread_key_t tpd_key;
-static int key_created = 0;
+static thread_key_t tpd_key = THR_ONCE_KEY;
static tnf_ops_t *stashed_tpd = NULL;
/*
@@ -612,21 +611,12 @@ void
tnf_thread_disable(void)
{
tnf_ops_t *ops;
- static mutex_t keylock = DEFAULTMUTEX;
if (thr_probe_setup != 0) {
/* threaded client */
- if (!key_created) {
- (void) mutex_lock(&keylock);
- if (!key_created) {
- /* REMIND: destructor function ? */
- (void) thr_keycreate(&tpd_key, NULL);
- key_created++;
- }
- (void) mutex_unlock(&keylock);
- }
-
+ /* REMIND: destructor function ? */
+ (void) thr_keycreate_once(&tpd_key, NULL);
/* get the tpd */
ops = thr_probe_getfunc_addr();
/* check ops to ensure function is idempotent */
@@ -663,19 +653,15 @@ tnf_thread_enable(void)
if (thr_probe_setup != 0) {
/* threaded client */
- if (key_created) {
- (void) thr_getspecific(tpd_key, (void *)&ops);
- if (ops) {
- thr_probe_setup(ops);
- }
- }
+ ops = pthread_getspecific(tpd_key);
+ if (ops)
+ thr_probe_setup(ops);
} else {
/* non-threaded client */
ops = stashed_tpd;
- if (ops) {
+ if (ops)
probe_setup(ops);
- }
}
}
@@ -711,10 +697,7 @@ common_fork(fork_t real_fork)
*/
if (thr_probe_setup != 0) {
/* threaded client */
- if (key_created) {
- (void) thr_getspecific(tpd_key,
- (void *)&ops);
- }
+ ops = pthread_getspecific(tpd_key);
} else {
/* non-threaded client */
ops = stashed_tpd;
diff --git a/usr/src/lib/libuutil/common/uu_misc.c b/usr/src/lib/libuutil/common/uu_misc.c
index c56e3d6dfc..74ec177c11 100644
--- a/usr/src/lib/libuutil/common/uu_misc.c
+++ b/usr/src/lib/libuutil/common/uu_misc.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -44,9 +44,23 @@
#define TEXT_DOMAIN "SYS_TEST"
#endif
+/*
+ * All of the old code under !defined(PTHREAD_ONCE_KEY_NP)
+ * is here to enable the building of a native version of
+ * libuutil.so when the build machine has not yet been upgraded
+ * to a version of libc that provides pthread_key_create_once_np().
+ * It should all be deleted when solaris_nevada ships.
+ * The code is not MT-safe in a relaxed memory model.
+ */
+
+#if defined(PTHREAD_ONCE_KEY_NP)
+static pthread_key_t uu_error_key = PTHREAD_ONCE_KEY_NP;
+#else /* PTHREAD_ONCE_KEY_NP */
+static pthread_key_t uu_error_key = 0;
static pthread_mutex_t uu_key_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_key_t uu_error_key;
-static int uu_error_key_setup;
+#endif /* PTHREAD_ONCE_KEY_NP */
+
+static int uu_error_key_setup = 0;
static pthread_mutex_t uu_panic_lock = PTHREAD_MUTEX_INITIALIZER;
/* LINTED static unused */
@@ -60,22 +74,27 @@ static uint32_t _uu_main_error;
void
uu_set_error(uint_t code)
{
- int error;
if (thr_main() != 0) {
_uu_main_error = code;
return;
}
+#if defined(PTHREAD_ONCE_KEY_NP)
+ if (pthread_key_create_once_np(&uu_error_key, NULL) != 0)
+ uu_error_key_setup = -1;
+ else
+ uu_error_key_setup = 1;
+#else /* PTHREAD_ONCE_KEY_NP */
if (uu_error_key_setup == 0) {
(void) pthread_mutex_lock(&uu_key_lock);
if (uu_error_key_setup == 0) {
- error = pthread_key_create(&uu_error_key, NULL);
- if (error != 0)
+ if (pthread_key_create(&uu_error_key, NULL) != 0)
uu_error_key_setup = -1;
else
uu_error_key_setup = 1;
}
(void) pthread_mutex_unlock(&uu_key_lock);
}
+#endif /* PTHREAD_ONCE_KEY_NP */
if (uu_error_key_setup > 0)
(void) pthread_setspecific(uu_error_key,
(void *)(uintptr_t)code);
@@ -87,12 +106,14 @@ uu_error(void)
if (thr_main() != 0)
return (_uu_main_error);
- if (uu_error_key_setup < 0)
+ if (uu_error_key_setup < 0) /* can't happen? */
return (UU_ERROR_UNKNOWN);
- else if (uu_error_key_setup == 0)
- return (UU_ERROR_NONE);
- else
- return ((uint32_t)(uintptr_t)pthread_getspecific(uu_error_key));
+
+ /*
+ * Because UU_ERROR_NONE == 0, if uu_set_error() was
+ * never called, then this will return UU_ERROR_NONE:
+ */
+ return ((uint32_t)(uintptr_t)pthread_getspecific(uu_error_key));
}
const char *
@@ -199,7 +220,9 @@ static void
uu_lockup(void)
{
(void) pthread_mutex_lock(&uu_panic_lock);
+#if !defined(PTHREAD_ONCE_KEY_NP)
(void) pthread_mutex_lock(&uu_key_lock);
+#endif
uu_avl_lockup();
uu_list_lockup();
}
@@ -208,7 +231,9 @@ static void
uu_release(void)
{
(void) pthread_mutex_unlock(&uu_panic_lock);
+#if !defined(PTHREAD_ONCE_KEY_NP)
(void) pthread_mutex_unlock(&uu_key_lock);
+#endif
uu_avl_release();
uu_list_release();
}
diff --git a/usr/src/lib/rpcsec_gss/rpcsec_gss.c b/usr/src/lib/rpcsec_gss/rpcsec_gss.c
index c71840304d..480532ccb5 100644
--- a/usr/src/lib/rpcsec_gss/rpcsec_gss.c
+++ b/usr/src/lib/rpcsec_gss/rpcsec_gss.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,9 +18,10 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright (c) 1986-1995, 1997, 2001 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -60,9 +60,9 @@ static bool_t validate_seqwin();
*/
extern bool_t xdr_opaque_auth(XDR *, struct opaque_auth *);
extern int _thr_main(void);
-extern int _thr_getspecific(thread_key_t key, void **valuep);
+extern void *_pthread_getspecific(pthread_key_t key);
typedef void (*PFrV) (void *);
-extern int _thr_keycreate(thread_key_t *pkey, PFrV destructor);
+extern int _thr_keycreate_once(thread_key_t *pkey, PFrV destructor);
extern int _thr_setspecific(unsigned int key, void *value);
@@ -124,19 +124,15 @@ __rpc_gss_seccreate(clnt, server_name, mech, service, qop, options_req,
AUTH *auth = NULL;
rpc_gss_data *ap = NULL;
OM_uint32 qop_num;
- rpc_gss_error_t error;
- void __rpc_gss_get_error();
/*
* convert ascii strings to GSS values
*/
if (!__rpc_gss_qop_to_num(qop, mech, &qop_num)) {
- __rpc_gss_get_error(&error);
return (NULL);
}
if (!__rpc_gss_mech_to_oid(mech, &mech_type)) {
- __rpc_gss_get_error(&error);
return (NULL);
}
@@ -900,46 +896,34 @@ __rpc_gss_max_data_length(auth, max_tp_unit_len)
max_tp_unit_len));
}
+void
+__rpc_gss_get_error(rpc_gss_error_t *error)
+{
+ *error = rpc_gss_err;
+}
+
#undef rpc_gss_err
rpc_gss_error_t rpc_gss_err;
-static mutex_t rge_lock; /* protects TSD key creation */
rpc_gss_error_t *
__rpc_gss_err()
{
- static thread_key_t rpc_gss_err_key = 0;
- rpc_gss_error_t *tsd = 0;
+ static thread_key_t rpc_gss_err_key = THR_ONCE_KEY;
+ rpc_gss_error_t *tsd;
if (_thr_main())
return (&rpc_gss_err);
- if (_thr_getspecific(rpc_gss_err_key, (void **) &tsd) != 0) {
- mutex_lock(&rge_lock);
- if (_thr_keycreate(&rpc_gss_err_key, free) != 0) {
- mutex_unlock(&rge_lock);
- return (&rpc_gss_err);
- }
- mutex_unlock(&rge_lock);
- }
- if (!tsd) {
- tsd = (rpc_gss_error_t *)
- calloc(1, sizeof (rpc_gss_error_t));
- if (_thr_setspecific(rpc_gss_err_key, (void *) tsd) != 0) {
+ if (_thr_keycreate_once(&rpc_gss_err_key, free) != 0)
+ return (&rpc_gss_err);
+ tsd = _pthread_getspecific(rpc_gss_err_key);
+ if (tsd == NULL) {
+ tsd = (rpc_gss_error_t *)calloc(1, sizeof (rpc_gss_error_t));
+ if (_thr_setspecific(rpc_gss_err_key, tsd) != 0) {
if (tsd)
free(tsd);
return (&rpc_gss_err);
}
- memset(tsd, 0, sizeof (rpc_gss_error_t));
- return (tsd);
}
return (tsd);
}
-
-void
-__rpc_gss_get_error(error)
- rpc_gss_error_t *error;
-{
-
- error->rpc_gss_error = rpc_gss_err.rpc_gss_error;
- error->system_error = rpc_gss_err.system_error;
-}