xref: /illumos-gate/usr/src/lib/libnsl/common/common.c (revision 814a60b13c0ad90e5d2edfd29a7a84bbf416cc1a)
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 /*
24  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 #include "mt.h"
31 #include <stdlib.h>
32 
33 void *
34 thr_get_storage(pthread_key_t *keyp, size_t size, void (*destructor)(void *))
35 {
36 	extern mutex_t tsd_lock;
37 	pthread_key_t key;
38 	void *addr;
39 
40 	if ((key = *keyp) == 0) {
41 		(void) mutex_lock(&tsd_lock);
42 		if ((key = *keyp) == 0) {
43 			if (pthread_key_create(keyp, destructor) != 0) {
44 				(void) mutex_unlock(&tsd_lock);
45 				return (NULL);
46 			}
47 			key = *keyp;
48 		}
49 		(void) mutex_unlock(&tsd_lock);
50 	}
51 
52 	addr = pthread_getspecific(key);
53 	if (addr == NULL && size != 0) {
54 		addr = calloc(1, size);
55 		if (addr != NULL && pthread_setspecific(key, addr) != 0) {
56 			free(addr);
57 			return (NULL);
58 		}
59 	}
60 
61 	return (addr);
62 }
63 
64 /*
65  * sig_mutex_lock() and sig_mutex_unlock() are the same
66  * as mutex_lock() and mutex_unlock() except that all
67  * signals are deferred while the lock is held.  Likewise
68  * for sig_rw_rdlock(), sig_rw_wrlock() and sig_rw_unlock().
69  *
70  * _sigoff() and _sigon() are consolidation-private
71  * interfaces in libc that defer and enable signals.
72  * Calls to these can nest but must be balanced, so
73  * nested calls to these functions work properly.
74  */
75 
76 void
77 sig_mutex_lock(mutex_t *mp)
78 {
79 	_sigoff();
80 	(void) mutex_lock(mp);
81 }
82 
83 void
84 sig_mutex_unlock(mutex_t *mp)
85 {
86 	(void) mutex_unlock(mp);
87 	_sigon();
88 }
89 
90 void
91 sig_rw_rdlock(rwlock_t *rwlp)
92 {
93 	_sigoff();
94 	(void) rw_rdlock(rwlp);
95 }
96 
97 void
98 sig_rw_wrlock(rwlock_t *rwlp)
99 {
100 	_sigoff();
101 	(void) rw_wrlock(rwlp);
102 }
103 
104 void
105 sig_rw_unlock(rwlock_t *rwlp)
106 {
107 	(void) rw_unlock(rwlp);
108 	_sigon();
109 }
110