xref: /titanic_51/usr/src/lib/libnsl/common/common.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1993-2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include "mt.h"
30 #include <stdlib.h>
31 
32 void *
33 thr_get_storage(pthread_key_t *keyp, size_t size, void (*destructor)(void *))
34 {
35 	extern mutex_t tsd_lock;
36 	pthread_key_t key;
37 	void *addr;
38 
39 	if ((key = *keyp) == 0) {
40 		mutex_lock(&tsd_lock);
41 		if ((key = *keyp) == 0) {
42 			if (pthread_key_create(keyp, destructor) != 0) {
43 				mutex_unlock(&tsd_lock);
44 				return (NULL);
45 			}
46 			key = *keyp;
47 		}
48 		mutex_unlock(&tsd_lock);
49 	}
50 
51 	addr = pthread_getspecific(key);
52 	if (addr == NULL && size != 0) {
53 		addr = calloc(1, size);
54 		if (addr != NULL && pthread_setspecific(key, addr) != 0) {
55 			free(addr);
56 			return (NULL);
57 		}
58 	}
59 
60 	return (addr);
61 }
62 
63 /*
64  * sig_mutex_lock() and sig_mutex_unlock() are the same
65  * as mutex_lock() and mutex_unlock() except that all
66  * signals are deferred while the lock is held.  Likewise
67  * for sig_rw_rdlock(), sig_rw_wrlock() and sig_rw_unlock().
68  *
69  * _sigoff() and _sigon() are consolidation-private
70  * interfaces in libc that defer and enable signals.
71  * Calls to these can nest but must be balanced, so
72  * nested calls to these functions work properly.
73  */
74 
75 void
76 sig_mutex_lock(mutex_t *mp)
77 {
78 	_sigoff();
79 	(void) mutex_lock(mp);
80 }
81 
82 void
83 sig_mutex_unlock(mutex_t *mp)
84 {
85 	(void) mutex_unlock(mp);
86 	_sigon();
87 }
88 
89 void
90 sig_rw_rdlock(rwlock_t *rwlp)
91 {
92 	_sigoff();
93 	(void) rw_rdlock(rwlp);
94 }
95 
96 void
97 sig_rw_wrlock(rwlock_t *rwlp)
98 {
99 	_sigoff();
100 	(void) rw_wrlock(rwlp);
101 }
102 
103 void
104 sig_rw_unlock(rwlock_t *rwlp)
105 {
106 	(void) rw_unlock(rwlp);
107 	_sigon();
108 }
109