4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Functions for managing thread-local storage for LDAP, and in particular
29 * for managing storage of the LDAP error state.
38 #include "solaris-int.h" /* This is a libladp5 private include file */
39 /* which has the defintion for */
40 /* struct ldap_extra_thread_fns */
41 #include "adutils_impl.h"
43 struct adutils_lderrno
{
49 static void *adutils_mutex_alloc(void);
50 static void adutils_mutex_free(void *mutexp
);
51 static int adutils_get_errno(void);
52 static void adutils_set_errno(int err
);
53 static void adutils_set_lderrno(int err
, char *matched
, char *errmsg
,
55 static int adutils_get_lderrno(char **matched
, char **errmsg
, void *dummy
);
56 static void adutils_lderrno_destructor(void *tsd
);
58 static pthread_key_t adutils_lderrno_key
= PTHREAD_ONCE_KEY_NP
;
60 static struct ldap_thread_fns thread_fns
= {
61 .ltf_mutex_alloc
= adutils_mutex_alloc
,
62 .ltf_mutex_free
= adutils_mutex_free
,
63 .ltf_mutex_lock
= (int (*)(void *)) pthread_mutex_lock
,
64 .ltf_mutex_unlock
= (int (*)(void *)) pthread_mutex_unlock
,
65 .ltf_get_errno
= adutils_get_errno
,
66 .ltf_set_errno
= adutils_set_errno
,
67 .ltf_get_lderrno
= adutils_get_lderrno
,
68 .ltf_set_lderrno
= adutils_set_lderrno
,
69 .ltf_lderrno_arg
= NULL
72 struct ldap_extra_thread_fns extra_thread_fns
= {
73 .ltf_threadid_fn
= (void * (*)(void))pthread_self
78 * Set up thread management functions for the specified LDAP session.
79 * Returns either LDAP_SUCCESS or -1.
82 adutils_set_thread_functions(LDAP
*ld
)
86 if (adutils_lderrno_key
== PTHREAD_ONCE_KEY_NP
) {
87 if ((rc
= pthread_key_create_once_np(&adutils_lderrno_key
,
88 adutils_lderrno_destructor
)) != 0) {
89 logger(LOG_ERR
, "adutils_set_thread_functions() "
90 "pthread_key_create_once_np failed (%s)",
97 rc
= ldap_set_option(ld
, LDAP_OPT_THREAD_FN_PTRS
,
99 if (rc
!= LDAP_SUCCESS
) {
101 "ldap_set_option LDAP_OPT_THREAD_FN_PTRS failed");
105 rc
= ldap_set_option(ld
, LDAP_OPT_EXTRA_THREAD_FN_PTRS
,
107 if (rc
!= LDAP_SUCCESS
) {
109 "ldap_set_option LDAP_OPT_EXTRA_THREAD_FN_PTRS failed");
120 adutils_mutex_alloc(void)
122 pthread_mutex_t
*mutexp
;
125 mutexp
= malloc(sizeof (pthread_mutex_t
));
126 if (mutexp
== NULL
) {
128 "adutils_mutex_alloc: malloc failed (%s)",
133 rc
= pthread_mutex_init(mutexp
, NULL
);
136 "adutils_mutex_alloc: "
137 "pthread_mutex_init failed (%s)",
150 adutils_mutex_free(void *mutexp
)
152 (void) pthread_mutex_destroy((pthread_mutex_t
*)mutexp
);
157 * Get the thread's local errno.
161 adutils_get_errno(void)
167 * Set the thread's local errno.
171 adutils_set_errno(int err
)
177 * Get a pointer to the thread's local LDAP error state structure.
178 * Lazily allocate the thread-local storage, so that we don't need
179 * initialization when each thread starts.
182 struct adutils_lderrno
*
183 adutils_get_lderrno_struct(void)
185 struct adutils_lderrno
*le
;
188 le
= pthread_getspecific(adutils_lderrno_key
);
190 le
= calloc(1, sizeof (*le
));
193 "adutils_get_lderrno_struct: calloc failed (%s)",
197 rc
= pthread_setspecific(adutils_lderrno_key
, le
);
200 "adutils_get_lderrno_struct: "
201 "pthread_setspecific failed (%s)",
212 * Store an error report in the thread's local LDAP error state structure.
216 adutils_set_lderrno(int err
, char *matched
, char *errmsg
, void *dummy
)
218 NOTE(ARGUNUSED(dummy
))
219 struct adutils_lderrno
*le
;
221 le
= adutils_get_lderrno_struct();
224 if (le
->le_matched
!= NULL
)
225 ldap_memfree(le
->le_matched
);
226 le
->le_matched
= matched
;
227 if (le
->le_errmsg
!= NULL
)
228 ldap_memfree(le
->le_errmsg
);
229 le
->le_errmsg
= errmsg
;
234 * Retrieve an error report from the thread's local LDAP error state structure.
238 adutils_get_lderrno(char **matched
, char **errmsg
, void *dummy
)
240 NOTE(ARGUNUSED(dummy
))
241 struct adutils_lderrno
*le
;
242 static struct adutils_lderrno empty
= { LDAP_SUCCESS
, NULL
, NULL
};
244 le
= adutils_get_lderrno_struct();
249 *matched
= le
->le_matched
;
251 *errmsg
= le
->le_errmsg
;
252 return (le
->le_errno
);
256 * Free the thread's local LDAP error state structure.
260 adutils_lderrno_destructor(void *tsd
)
262 struct adutils_lderrno
*le
= tsd
;
267 if (le
->le_matched
!= NULL
) {
268 ldap_memfree(le
->le_matched
);
269 le
->le_matched
= NULL
;
271 if (le
->le_errmsg
!= NULL
) {
272 ldap_memfree(le
->le_errmsg
);
273 le
->le_errmsg
= NULL
;