17c478bd9Sstevel@tonic-gate /* 2d4204c85Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 77c478bd9Sstevel@tonic-gate 87c478bd9Sstevel@tonic-gate 97c478bd9Sstevel@tonic-gate /* 107c478bd9Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public 117c478bd9Sstevel@tonic-gate * License Version 1.1 (the "License"); you may not use this file 127c478bd9Sstevel@tonic-gate * except in compliance with the License. You may obtain a copy of 137c478bd9Sstevel@tonic-gate * the License at http://www.mozilla.org/NPL/ 147c478bd9Sstevel@tonic-gate * 157c478bd9Sstevel@tonic-gate * Software distributed under the License is distributed on an "AS 167c478bd9Sstevel@tonic-gate * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 177c478bd9Sstevel@tonic-gate * implied. See the License for the specific language governing 187c478bd9Sstevel@tonic-gate * rights and limitations under the License. 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * The Original Code is Mozilla Communicator client code, released 217c478bd9Sstevel@tonic-gate * March 31, 1998. 227c478bd9Sstevel@tonic-gate * 237c478bd9Sstevel@tonic-gate * The Initial Developer of the Original Code is Netscape 247c478bd9Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are 257c478bd9Sstevel@tonic-gate * Copyright (C) 1998-1999 Netscape Communications Corporation. All 267c478bd9Sstevel@tonic-gate * Rights Reserved. 277c478bd9Sstevel@tonic-gate * 287c478bd9Sstevel@tonic-gate * Contributor(s): 297c478bd9Sstevel@tonic-gate */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate /* 327c478bd9Sstevel@tonic-gate * Thread callback functions for libldap that use the NSPR (Netscape 337c478bd9Sstevel@tonic-gate * Portable Runtime) thread API. 347c478bd9Sstevel@tonic-gate * 357c478bd9Sstevel@tonic-gate */ 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK 387c478bd9Sstevel@tonic-gate #include <thread.h> 397c478bd9Sstevel@tonic-gate #include <synch.h> 407c478bd9Sstevel@tonic-gate #include <prinit.h> 417c478bd9Sstevel@tonic-gate #include <prthread.h> 427c478bd9Sstevel@tonic-gate #include <syslog.h> 437c478bd9Sstevel@tonic-gate #include <string.h> 447c478bd9Sstevel@tonic-gate #include <sys/types.h> 457c478bd9Sstevel@tonic-gate #include <signal.h> 467c478bd9Sstevel@tonic-gate #include <errno.h> 477c478bd9Sstevel@tonic-gate extern int errno; 487c478bd9Sstevel@tonic-gate #endif /* _SOLARIS_SDK */ 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #include "ldappr-int.h" 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate #ifndef _SOLARIS_SDK 537c478bd9Sstevel@tonic-gate /* 547c478bd9Sstevel@tonic-gate * Macros: 557c478bd9Sstevel@tonic-gate */ 567c478bd9Sstevel@tonic-gate /* 577c478bd9Sstevel@tonic-gate * Grow thread private data arrays 10 elements at a time. 587c478bd9Sstevel@tonic-gate */ 597c478bd9Sstevel@tonic-gate #define PRLDAP_TPD_ARRAY_INCREMENT 10 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate /* 627c478bd9Sstevel@tonic-gate * Structures and types: 637c478bd9Sstevel@tonic-gate */ 647c478bd9Sstevel@tonic-gate /* 657c478bd9Sstevel@tonic-gate * Structure used by libldap thread callbacks to maintain error information. 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate typedef struct prldap_errorinfo { 687c478bd9Sstevel@tonic-gate int plei_lderrno; 697c478bd9Sstevel@tonic-gate char *plei_matched; 707c478bd9Sstevel@tonic-gate char *plei_errmsg; 717c478bd9Sstevel@tonic-gate } PRLDAP_ErrorInfo; 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate /* 747c478bd9Sstevel@tonic-gate * Structure used to maintain thread-private data. At the present time, 757c478bd9Sstevel@tonic-gate * only error info. is thread-private. One of these structures is allocated 767c478bd9Sstevel@tonic-gate * for each thread. 777c478bd9Sstevel@tonic-gate */ 787c478bd9Sstevel@tonic-gate typedef struct prldap_tpd_header { 797c478bd9Sstevel@tonic-gate int ptpdh_tpd_count; /* # of data items allocated */ 807c478bd9Sstevel@tonic-gate void **ptpdh_dataitems; /* array of data items */ 817c478bd9Sstevel@tonic-gate } PRLDAP_TPDHeader; 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate /* 847c478bd9Sstevel@tonic-gate * Structure used by associate a PRLDAP thread-private data index with an 857c478bd9Sstevel@tonic-gate * LDAP session handle. One of these exists for each active LDAP session 867c478bd9Sstevel@tonic-gate * handle. 877c478bd9Sstevel@tonic-gate */ 887c478bd9Sstevel@tonic-gate typedef struct prldap_tpd_map { 897c478bd9Sstevel@tonic-gate LDAP *prtm_ld; /* non-NULL if in use */ 907c478bd9Sstevel@tonic-gate PRUintn prtm_index; /* index into TPD array */ 917c478bd9Sstevel@tonic-gate struct prldap_tpd_map *prtm_next; 927c478bd9Sstevel@tonic-gate } PRLDAP_TPDMap; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK 957c478bd9Sstevel@tonic-gate extern mutex_t inited_mutex; 967c478bd9Sstevel@tonic-gate #endif /* _SOLARIS_SDK */ 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate /* 997c478bd9Sstevel@tonic-gate * Static Variables: 1007c478bd9Sstevel@tonic-gate */ 1017c478bd9Sstevel@tonic-gate /* 1027c478bd9Sstevel@tonic-gate * prldap_map_list points to all of the PRLDAP_TPDMap structures 1037c478bd9Sstevel@tonic-gate * we have ever allocated. We recycle them as we open and close LDAP 1047c478bd9Sstevel@tonic-gate * sessions. 1057c478bd9Sstevel@tonic-gate */ 1067c478bd9Sstevel@tonic-gate static PRLDAP_TPDMap *prldap_map_list = NULL; 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate /* 1107c478bd9Sstevel@tonic-gate * The prldap_map_mutex is used to protect access to the prldap_map_list. 1117c478bd9Sstevel@tonic-gate */ 1127c478bd9Sstevel@tonic-gate static PRLock *prldap_map_mutex = NULL; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate /* 1157c478bd9Sstevel@tonic-gate * The prldap_tpd_maxindex value is used to track the largest TPD array 1167c478bd9Sstevel@tonic-gate * index we have used. 1177c478bd9Sstevel@tonic-gate */ 1187c478bd9Sstevel@tonic-gate static PRInt32 prldap_tpd_maxindex = -1; 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate /* 1217c478bd9Sstevel@tonic-gate * prldap_tpdindex is an NSPR thread private data index we use to 1227c478bd9Sstevel@tonic-gate * maintain our own thread-private data. It is initialized inside 1237c478bd9Sstevel@tonic-gate * prldap_init_tpd(). 1247c478bd9Sstevel@tonic-gate */ 1257c478bd9Sstevel@tonic-gate static PRUintn prldap_tpdindex = 0; 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate /* 1287c478bd9Sstevel@tonic-gate * The prldap_callonce_init_tpd structure is used by NSPR to ensure 1297c478bd9Sstevel@tonic-gate * that prldap_init_tpd() is called at most once. 1307c478bd9Sstevel@tonic-gate */ 1317c478bd9Sstevel@tonic-gate static PRCallOnceType prldap_callonce_init_tpd = { 0, 0, 0 }; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /* 1357c478bd9Sstevel@tonic-gate * Private function prototypes: 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate static void prldap_set_ld_error( int err, char *matched, char *errmsg, 1387c478bd9Sstevel@tonic-gate void *errorarg ); 1397c478bd9Sstevel@tonic-gate static int prldap_get_ld_error( char **matchedp, char **errmsgp, 1407c478bd9Sstevel@tonic-gate void *errorarg ); 1417c478bd9Sstevel@tonic-gate #endif 1427c478bd9Sstevel@tonic-gate static void *prldap_mutex_alloc( void ); 1437c478bd9Sstevel@tonic-gate static void prldap_mutex_free( void *mutex ); 1447c478bd9Sstevel@tonic-gate static int prldap_mutex_lock( void *mutex ); 1457c478bd9Sstevel@tonic-gate static int prldap_mutex_unlock( void *mutex ); 1467c478bd9Sstevel@tonic-gate static void *prldap_get_thread_id( void ); 1477c478bd9Sstevel@tonic-gate #ifndef _SOLARIS_SDK 1487c478bd9Sstevel@tonic-gate static PRStatus prldap_init_tpd( void ); 1497c478bd9Sstevel@tonic-gate static PRLDAP_TPDMap *prldap_allocate_map( LDAP *ld ); 1507c478bd9Sstevel@tonic-gate static void prldap_return_map( PRLDAP_TPDMap *map ); 1517c478bd9Sstevel@tonic-gate static PRUintn prldap_new_tpdindex( void ); 1527c478bd9Sstevel@tonic-gate static int prldap_set_thread_private( PRInt32 tpdindex, void *priv ); 1537c478bd9Sstevel@tonic-gate static void *prldap_get_thread_private( PRInt32 tpdindex ); 1547c478bd9Sstevel@tonic-gate static PRLDAP_TPDHeader *prldap_tsd_realloc( PRLDAP_TPDHeader *tsdhdr, 1557c478bd9Sstevel@tonic-gate int maxindex ); 1567c478bd9Sstevel@tonic-gate static void prldap_tsd_destroy( void *priv ); 1577c478bd9Sstevel@tonic-gate #endif 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate /* 1617c478bd9Sstevel@tonic-gate * Install NSPR thread functions into ld (if ld is NULL, they are installed 1627c478bd9Sstevel@tonic-gate * as the default functions for new LDAP * handles). 1637c478bd9Sstevel@tonic-gate * 1647c478bd9Sstevel@tonic-gate * Returns 0 if all goes well and -1 if not. 1657c478bd9Sstevel@tonic-gate */ 1667c478bd9Sstevel@tonic-gate int 1677c478bd9Sstevel@tonic-gate prldap_install_thread_functions( LDAP *ld, int shared ) 1687c478bd9Sstevel@tonic-gate { 1697c478bd9Sstevel@tonic-gate struct ldap_thread_fns tfns; 1707c478bd9Sstevel@tonic-gate struct ldap_extra_thread_fns xtfns; 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate #ifndef _SOLARIS_SDK 1737c478bd9Sstevel@tonic-gate if ( PR_CallOnce( &prldap_callonce_init_tpd, prldap_init_tpd ) 1747c478bd9Sstevel@tonic-gate != PR_SUCCESS ) { 1757c478bd9Sstevel@tonic-gate ldap_set_lderrno( ld, LDAP_LOCAL_ERROR, NULL, NULL ); 1767c478bd9Sstevel@tonic-gate return( -1 ); 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate #endif /* _SOLARIS_SDK */ 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate /* set thread function pointers */ 1817c478bd9Sstevel@tonic-gate memset( &tfns, '\0', sizeof(struct ldap_thread_fns) ); 1827c478bd9Sstevel@tonic-gate tfns.ltf_get_errno = prldap_get_system_errno; 1837c478bd9Sstevel@tonic-gate tfns.ltf_set_errno = prldap_set_system_errno; 1847c478bd9Sstevel@tonic-gate if ( shared ) { 1857c478bd9Sstevel@tonic-gate tfns.ltf_mutex_alloc = prldap_mutex_alloc; 1867c478bd9Sstevel@tonic-gate tfns.ltf_mutex_free = prldap_mutex_free; 1877c478bd9Sstevel@tonic-gate tfns.ltf_mutex_lock = prldap_mutex_lock; 1887c478bd9Sstevel@tonic-gate tfns.ltf_mutex_unlock = prldap_mutex_unlock; 1897c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK 1907c478bd9Sstevel@tonic-gate tfns.ltf_get_lderrno = NULL; 1917c478bd9Sstevel@tonic-gate tfns.ltf_set_lderrno = NULL; 1927c478bd9Sstevel@tonic-gate #else 1937c478bd9Sstevel@tonic-gate tfns.ltf_get_lderrno = prldap_get_ld_error; 1947c478bd9Sstevel@tonic-gate tfns.ltf_set_lderrno = prldap_set_ld_error; 1957c478bd9Sstevel@tonic-gate if ( ld != NULL ) { 1967c478bd9Sstevel@tonic-gate /* 1977c478bd9Sstevel@tonic-gate * If this is a real ld (i.e., we are not setting the global 1987c478bd9Sstevel@tonic-gate * defaults) allocate thread private data for error information. 1997c478bd9Sstevel@tonic-gate * If ld is NULL we do not do this here but it is done in 2007c478bd9Sstevel@tonic-gate * prldap_thread_new_handle(). 2017c478bd9Sstevel@tonic-gate */ 2027c478bd9Sstevel@tonic-gate if (( tfns.ltf_lderrno_arg = (void *)prldap_allocate_map( ld )) 2037c478bd9Sstevel@tonic-gate == NULL ) { 2047c478bd9Sstevel@tonic-gate return( -1 ); 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate #endif 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate if ( ldap_set_option( ld, LDAP_OPT_THREAD_FN_PTRS, 2117c478bd9Sstevel@tonic-gate (void *)&tfns ) != 0 ) { 2127c478bd9Sstevel@tonic-gate #ifndef _SOLARIS_SDK 2137c478bd9Sstevel@tonic-gate prldap_return_map( (PRLDAP_TPDMap *)tfns.ltf_lderrno_arg ); 2147c478bd9Sstevel@tonic-gate #endif 2157c478bd9Sstevel@tonic-gate return( -1 ); 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate /* set extended thread function pointers */ 2197c478bd9Sstevel@tonic-gate memset( &xtfns, '\0', sizeof(struct ldap_extra_thread_fns) ); 2207c478bd9Sstevel@tonic-gate xtfns.ltf_threadid_fn = prldap_get_thread_id; 2217c478bd9Sstevel@tonic-gate if ( ldap_set_option( ld, LDAP_OPT_EXTRA_THREAD_FN_PTRS, 2227c478bd9Sstevel@tonic-gate (void *)&xtfns ) != 0 ) { 2237c478bd9Sstevel@tonic-gate return( -1 ); 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate return( 0 ); 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate static void * 2317c478bd9Sstevel@tonic-gate prldap_mutex_alloc( void ) 2327c478bd9Sstevel@tonic-gate { 2337c478bd9Sstevel@tonic-gate return( (void *)PR_NewLock()); 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate static void 2387c478bd9Sstevel@tonic-gate prldap_mutex_free( void *mutex ) 2397c478bd9Sstevel@tonic-gate { 2407c478bd9Sstevel@tonic-gate PR_DestroyLock( (PRLock *)mutex ); 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate static int 2457c478bd9Sstevel@tonic-gate prldap_mutex_lock( void *mutex ) 2467c478bd9Sstevel@tonic-gate { 2477c478bd9Sstevel@tonic-gate PR_Lock( (PRLock *)mutex ); 2487c478bd9Sstevel@tonic-gate return( 0 ); 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate static int 2537c478bd9Sstevel@tonic-gate prldap_mutex_unlock( void *mutex ) 2547c478bd9Sstevel@tonic-gate { 2557c478bd9Sstevel@tonic-gate if ( PR_Unlock( (PRLock *)mutex ) == PR_FAILURE ) { 2567c478bd9Sstevel@tonic-gate return( -1 ); 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate return( 0 ); 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate static void * 2647c478bd9Sstevel@tonic-gate prldap_get_thread_id( void ) 2657c478bd9Sstevel@tonic-gate { 2667c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK 2677c478bd9Sstevel@tonic-gate return ((void *)thr_self()); 2687c478bd9Sstevel@tonic-gate #else 2697c478bd9Sstevel@tonic-gate return( (void *)PR_GetCurrentThread()); 2707c478bd9Sstevel@tonic-gate #endif 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate #ifndef _SOLARIS_SDK 2747c478bd9Sstevel@tonic-gate static int 2757c478bd9Sstevel@tonic-gate prldap_get_ld_error( char **matchedp, char **errmsgp, void *errorarg ) 2767c478bd9Sstevel@tonic-gate { 2777c478bd9Sstevel@tonic-gate PRLDAP_TPDMap *map; 2787c478bd9Sstevel@tonic-gate PRLDAP_ErrorInfo *eip; 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate if (( map = (PRLDAP_TPDMap *)errorarg ) != NULL && ( eip = 2817c478bd9Sstevel@tonic-gate (PRLDAP_ErrorInfo *)prldap_get_thread_private( 2827c478bd9Sstevel@tonic-gate map->prtm_index )) != NULL ) { 2837c478bd9Sstevel@tonic-gate if ( matchedp != NULL ) { 2847c478bd9Sstevel@tonic-gate *matchedp = eip->plei_matched; 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate if ( errmsgp != NULL ) { 2877c478bd9Sstevel@tonic-gate *errmsgp = eip->plei_errmsg; 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate return( eip->plei_lderrno ); 2907c478bd9Sstevel@tonic-gate } else { 2917c478bd9Sstevel@tonic-gate if ( matchedp != NULL ) { 2927c478bd9Sstevel@tonic-gate *matchedp = NULL; 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate if ( errmsgp != NULL ) { 2957c478bd9Sstevel@tonic-gate *errmsgp = NULL; 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate return( LDAP_LOCAL_ERROR ); /* punt */ 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate static void 3037c478bd9Sstevel@tonic-gate prldap_set_ld_error( int err, char *matched, char *errmsg, void *errorarg ) 3047c478bd9Sstevel@tonic-gate { 3057c478bd9Sstevel@tonic-gate PRLDAP_TPDMap *map; 3067c478bd9Sstevel@tonic-gate PRLDAP_ErrorInfo *eip; 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate if (( map = (PRLDAP_TPDMap *)errorarg ) != NULL ) { 3097c478bd9Sstevel@tonic-gate if (( eip = (PRLDAP_ErrorInfo *)prldap_get_thread_private( 3107c478bd9Sstevel@tonic-gate map->prtm_index )) == NULL ) { 3117c478bd9Sstevel@tonic-gate /* 3127c478bd9Sstevel@tonic-gate * Error info. has not yet been allocated for this thread. 3137c478bd9Sstevel@tonic-gate * Do so now. Note that we free this memory only for the 3147c478bd9Sstevel@tonic-gate * thread that calls prldap_thread_dispose_handle(), which 3157c478bd9Sstevel@tonic-gate * should be the one that called ldap_unbind() -- see 3167c478bd9Sstevel@tonic-gate * prldap_return_map(). Not freeing the memory used by 3177c478bd9Sstevel@tonic-gate * other threads is deemed acceptable since it will be 3187c478bd9Sstevel@tonic-gate * recycled and used by other LDAP sessions. All of the 3197c478bd9Sstevel@tonic-gate * thread-private memory is freed when a thread exits 3207c478bd9Sstevel@tonic-gate * (inside the prldap_tsd_destroy() function). 3217c478bd9Sstevel@tonic-gate */ 3227c478bd9Sstevel@tonic-gate eip = (PRLDAP_ErrorInfo *)PR_Calloc( 1, 3237c478bd9Sstevel@tonic-gate sizeof( PRLDAP_ErrorInfo )); 3247c478bd9Sstevel@tonic-gate if ( eip == NULL ) { 3257c478bd9Sstevel@tonic-gate return; /* punt */ 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate (void)prldap_set_thread_private( map->prtm_index, eip ); 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate eip->plei_lderrno = err; 3317c478bd9Sstevel@tonic-gate if ( eip->plei_matched != NULL ) { 3327c478bd9Sstevel@tonic-gate ldap_memfree( eip->plei_matched ); 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate eip->plei_matched = matched; 3357c478bd9Sstevel@tonic-gate if ( eip->plei_errmsg != NULL ) { 3367c478bd9Sstevel@tonic-gate ldap_memfree( eip->plei_errmsg ); 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate eip->plei_errmsg = errmsg; 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate #endif 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate /* 3457c478bd9Sstevel@tonic-gate * Called when a new LDAP * session handle is allocated. 3467c478bd9Sstevel@tonic-gate * Allocate thread-private data for error information, but only if 3477c478bd9Sstevel@tonic-gate * it has not already been allocated and the get_ld_error callback has 3487c478bd9Sstevel@tonic-gate * been installed. If ld is not NULL when prldap_install_thread_functions() 3497c478bd9Sstevel@tonic-gate * is called, we will have already allocated the thread-private data there. 3507c478bd9Sstevel@tonic-gate */ 3517c478bd9Sstevel@tonic-gate int 3527c478bd9Sstevel@tonic-gate prldap_thread_new_handle( LDAP *ld, void *sessionarg ) 3537c478bd9Sstevel@tonic-gate { 3547c478bd9Sstevel@tonic-gate struct ldap_thread_fns tfns; 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate #ifndef _SOLARIS_SDK 3577c478bd9Sstevel@tonic-gate if ( ldap_get_option( ld, LDAP_OPT_THREAD_FN_PTRS, (void *)&tfns ) != 0 ) { 3587c478bd9Sstevel@tonic-gate return( LDAP_LOCAL_ERROR ); 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate if ( tfns.ltf_lderrno_arg == NULL && tfns.ltf_get_lderrno != NULL ) { 3627c478bd9Sstevel@tonic-gate if (( tfns.ltf_lderrno_arg = (void *)prldap_allocate_map( ld )) == NULL 3637c478bd9Sstevel@tonic-gate || ldap_set_option( ld, LDAP_OPT_THREAD_FN_PTRS, 3647c478bd9Sstevel@tonic-gate (void *)&tfns ) != 0 ) { 3657c478bd9Sstevel@tonic-gate return( LDAP_LOCAL_ERROR ); 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate #endif 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate return( LDAP_SUCCESS ); 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate /* 3757c478bd9Sstevel@tonic-gate * Called when an LDAP * session handle is being destroyed. 3767c478bd9Sstevel@tonic-gate * Clean up our thread private data map. 3777c478bd9Sstevel@tonic-gate */ 3787c478bd9Sstevel@tonic-gate void 3797c478bd9Sstevel@tonic-gate prldap_thread_dispose_handle( LDAP *ld, void *sessionarg ) 3807c478bd9Sstevel@tonic-gate { 3817c478bd9Sstevel@tonic-gate #ifndef _SOLARIS_SDK 3827c478bd9Sstevel@tonic-gate struct ldap_thread_fns tfns; 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate if ( ldap_get_option( ld, LDAP_OPT_THREAD_FN_PTRS, 3857c478bd9Sstevel@tonic-gate (void *)&tfns ) == 0 && 3867c478bd9Sstevel@tonic-gate tfns.ltf_lderrno_arg != NULL ) { 3877c478bd9Sstevel@tonic-gate prldap_return_map( (PRLDAP_TPDMap *)tfns.ltf_lderrno_arg ); 3887c478bd9Sstevel@tonic-gate } 3897c478bd9Sstevel@tonic-gate #endif 3907c478bd9Sstevel@tonic-gate } 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate #ifndef _SOLARIS_SDK 3947c478bd9Sstevel@tonic-gate static PRStatus 3957c478bd9Sstevel@tonic-gate prldap_init_tpd( void ) 3967c478bd9Sstevel@tonic-gate { 3977c478bd9Sstevel@tonic-gate if (( prldap_map_mutex = PR_NewLock()) == NULL || PR_NewThreadPrivateIndex( 3987c478bd9Sstevel@tonic-gate &prldap_tpdindex, prldap_tsd_destroy ) != PR_SUCCESS ) { 3997c478bd9Sstevel@tonic-gate return( PR_FAILURE ); 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate prldap_map_list = NULL; 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate return( PR_SUCCESS ); 4057c478bd9Sstevel@tonic-gate } 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate /* 4097c478bd9Sstevel@tonic-gate * Function: prldap_allocate_map() 4107c478bd9Sstevel@tonic-gate * Description: allocate a thread-private data map to use for a new 4117c478bd9Sstevel@tonic-gate * LDAP session handle. 4127c478bd9Sstevel@tonic-gate * Returns: a pointer to the TPD map or NULL if none available. 4137c478bd9Sstevel@tonic-gate */ 4147c478bd9Sstevel@tonic-gate static PRLDAP_TPDMap * 4157c478bd9Sstevel@tonic-gate prldap_allocate_map( LDAP *ld ) 4167c478bd9Sstevel@tonic-gate { 4177c478bd9Sstevel@tonic-gate PRLDAP_TPDMap *map, *prevmap; 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate PR_Lock( prldap_map_mutex ); 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate /* 4227c478bd9Sstevel@tonic-gate * first look for a map that is already allocated but free to be re-used 4237c478bd9Sstevel@tonic-gate */ 4247c478bd9Sstevel@tonic-gate prevmap = NULL; 4257c478bd9Sstevel@tonic-gate for ( map = prldap_map_list; map != NULL; map = map->prtm_next ) { 4267c478bd9Sstevel@tonic-gate if ( map->prtm_ld == NULL ) { 4277c478bd9Sstevel@tonic-gate break; 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate prevmap = map; 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate /* 4337c478bd9Sstevel@tonic-gate * if none we found (map == NULL), try to allocate a new one and add it 4347c478bd9Sstevel@tonic-gate * to the end of our global list. 4357c478bd9Sstevel@tonic-gate */ 4367c478bd9Sstevel@tonic-gate if ( map == NULL ) { 4377c478bd9Sstevel@tonic-gate PRUintn tpdindex; 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate tpdindex = prldap_new_tpdindex(); 4407c478bd9Sstevel@tonic-gate map = (PRLDAP_TPDMap *)PR_Malloc( sizeof( PRLDAP_TPDMap )); 4417c478bd9Sstevel@tonic-gate if ( map != NULL ) { 4427c478bd9Sstevel@tonic-gate map->prtm_index = tpdindex; 4437c478bd9Sstevel@tonic-gate map->prtm_next = NULL; 4447c478bd9Sstevel@tonic-gate if ( prevmap == NULL ) { 4457c478bd9Sstevel@tonic-gate prldap_map_list = map; 4467c478bd9Sstevel@tonic-gate } else { 4477c478bd9Sstevel@tonic-gate prevmap->prtm_next = map; 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate } 4507c478bd9Sstevel@tonic-gate } 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate if ( map != NULL ) { 4537c478bd9Sstevel@tonic-gate map->prtm_ld = ld; /* now marked as "in use" */ 4547c478bd9Sstevel@tonic-gate /* since we are reusing...reset */ 4557c478bd9Sstevel@tonic-gate /* to initial state */ 4567c478bd9Sstevel@tonic-gate (void)prldap_set_thread_private( map->prtm_index, NULL ); 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate PR_Unlock( prldap_map_mutex ); 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate return( map ); 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate /* 4667c478bd9Sstevel@tonic-gate * Function: prldap_return_map() 4677c478bd9Sstevel@tonic-gate * Description: return a thread-private data map to the pool of ones 4687c478bd9Sstevel@tonic-gate * available for re-use. 4697c478bd9Sstevel@tonic-gate */ 4707c478bd9Sstevel@tonic-gate static void 4717c478bd9Sstevel@tonic-gate prldap_return_map( PRLDAP_TPDMap *map ) 4727c478bd9Sstevel@tonic-gate { 4737c478bd9Sstevel@tonic-gate PRLDAP_ErrorInfo *eip; 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate PR_Lock( prldap_map_mutex ); 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate /* 4787c478bd9Sstevel@tonic-gate * Dispose of thread-private LDAP error information. Note that this 4797c478bd9Sstevel@tonic-gate * only disposes of the memory consumed on THIS thread, but that is 4807c478bd9Sstevel@tonic-gate * okay. See the comment in prldap_set_ld_error() for the reason why. 4817c478bd9Sstevel@tonic-gate */ 4827c478bd9Sstevel@tonic-gate if (( eip = (PRLDAP_ErrorInfo *)prldap_get_thread_private( 4837c478bd9Sstevel@tonic-gate map->prtm_index )) != NULL && 4847c478bd9Sstevel@tonic-gate prldap_set_thread_private( map->prtm_index, NULL ) == 0 ) { 4857c478bd9Sstevel@tonic-gate if ( eip->plei_matched != NULL ) { 4867c478bd9Sstevel@tonic-gate ldap_memfree( eip->plei_matched ); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate if ( eip->plei_errmsg != NULL ) { 4897c478bd9Sstevel@tonic-gate ldap_memfree( eip->plei_errmsg ); 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate PR_Free( eip ); 4937c478bd9Sstevel@tonic-gate } 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate /* mark map as available for re-use */ 4967c478bd9Sstevel@tonic-gate map->prtm_ld = NULL; 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate PR_Unlock( prldap_map_mutex ); 4997c478bd9Sstevel@tonic-gate } 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate /* 5037c478bd9Sstevel@tonic-gate * Function: prldap_new_tpdindex() 5047c478bd9Sstevel@tonic-gate * Description: allocate a thread-private data index. 5057c478bd9Sstevel@tonic-gate * Returns: the new index. 5067c478bd9Sstevel@tonic-gate */ 5077c478bd9Sstevel@tonic-gate static PRUintn 5087c478bd9Sstevel@tonic-gate prldap_new_tpdindex( void ) 5097c478bd9Sstevel@tonic-gate { 5107c478bd9Sstevel@tonic-gate PRUintn tpdindex; 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate tpdindex = (PRUintn)PR_AtomicIncrement( &prldap_tpd_maxindex ); 5137c478bd9Sstevel@tonic-gate return( tpdindex ); 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate /* 5187c478bd9Sstevel@tonic-gate * Function: prldap_set_thread_private() 5197c478bd9Sstevel@tonic-gate * Description: store a piece of thread-private data. 5207c478bd9Sstevel@tonic-gate * Returns: 0 if successful and -1 if not. 5217c478bd9Sstevel@tonic-gate */ 5227c478bd9Sstevel@tonic-gate static int 5237c478bd9Sstevel@tonic-gate prldap_set_thread_private( PRInt32 tpdindex, void *priv ) 5247c478bd9Sstevel@tonic-gate { 5257c478bd9Sstevel@tonic-gate PRLDAP_TPDHeader *tsdhdr; 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate if ( tpdindex > prldap_tpd_maxindex ) { 5287c478bd9Sstevel@tonic-gate return( -1 ); /* bad index */ 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate tsdhdr = (PRLDAP_TPDHeader *)PR_GetThreadPrivate( prldap_tpdindex ); 5327c478bd9Sstevel@tonic-gate if ( tsdhdr == NULL || tpdindex >= tsdhdr->ptpdh_tpd_count ) { 5337c478bd9Sstevel@tonic-gate tsdhdr = prldap_tsd_realloc( tsdhdr, tpdindex ); 5347c478bd9Sstevel@tonic-gate if ( tsdhdr == NULL ) { 5357c478bd9Sstevel@tonic-gate return( -1 ); /* realloc failed */ 5367c478bd9Sstevel@tonic-gate } 5377c478bd9Sstevel@tonic-gate } 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate tsdhdr->ptpdh_dataitems[ tpdindex ] = priv; 5407c478bd9Sstevel@tonic-gate return( 0 ); 5417c478bd9Sstevel@tonic-gate } 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate /* 5457c478bd9Sstevel@tonic-gate * Function: prldap_get_thread_private() 5467c478bd9Sstevel@tonic-gate * Description: retrieve a piece of thread-private data. If not set, 5477c478bd9Sstevel@tonic-gate * NULL is returned. 5487c478bd9Sstevel@tonic-gate * Returns: 0 if successful and -1 if not. 5497c478bd9Sstevel@tonic-gate */ 5507c478bd9Sstevel@tonic-gate static void * 5517c478bd9Sstevel@tonic-gate prldap_get_thread_private( PRInt32 tpdindex ) 5527c478bd9Sstevel@tonic-gate { 5537c478bd9Sstevel@tonic-gate PRLDAP_TPDHeader *tsdhdr; 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate tsdhdr = (PRLDAP_TPDHeader *)PR_GetThreadPrivate( prldap_tpdindex ); 5567c478bd9Sstevel@tonic-gate if ( tsdhdr == NULL ) { 5577c478bd9Sstevel@tonic-gate return( NULL ); /* no thread private data */ 5587c478bd9Sstevel@tonic-gate } 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate if ( tpdindex >= tsdhdr->ptpdh_tpd_count 5617c478bd9Sstevel@tonic-gate || tsdhdr->ptpdh_dataitems == NULL ) { 5627c478bd9Sstevel@tonic-gate return( NULL ); /* fewer data items than requested index */ 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate return( tsdhdr->ptpdh_dataitems[ tpdindex ] ); 5667c478bd9Sstevel@tonic-gate } 5677c478bd9Sstevel@tonic-gate 5687c478bd9Sstevel@tonic-gate 5697c478bd9Sstevel@tonic-gate /* 5707c478bd9Sstevel@tonic-gate * Function: prldap_tsd_realloc() 5717c478bd9Sstevel@tonic-gate * Description: enlarge the thread-private data array. 5727c478bd9Sstevel@tonic-gate * Returns: the new PRLDAP_TPDHeader value (non-NULL if successful). 5737c478bd9Sstevel@tonic-gate * Note: tsdhdr can be NULL (allocates a new PRLDAP_TPDHeader). 5747c478bd9Sstevel@tonic-gate */ 5757c478bd9Sstevel@tonic-gate static PRLDAP_TPDHeader * 5767c478bd9Sstevel@tonic-gate prldap_tsd_realloc( PRLDAP_TPDHeader *tsdhdr, int maxindex ) 5777c478bd9Sstevel@tonic-gate { 5787c478bd9Sstevel@tonic-gate void *newdataitems = NULL; 5797c478bd9Sstevel@tonic-gate int count; 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate if ( tsdhdr == NULL ) { 5827c478bd9Sstevel@tonic-gate /* allocate a new thread private data header */ 5837c478bd9Sstevel@tonic-gate if (( tsdhdr = PR_Calloc( 1, sizeof( PRLDAP_TPDHeader ))) == NULL ) { 5847c478bd9Sstevel@tonic-gate return( NULL ); 5857c478bd9Sstevel@tonic-gate } 5867c478bd9Sstevel@tonic-gate (void)PR_SetThreadPrivate( prldap_tpdindex, tsdhdr ); 5877c478bd9Sstevel@tonic-gate } 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate /* 5907c478bd9Sstevel@tonic-gate * Make the size of the new array the next highest multiple of 5917c478bd9Sstevel@tonic-gate * the array increment value that is greater than maxindex. 5927c478bd9Sstevel@tonic-gate */ 5937c478bd9Sstevel@tonic-gate count = PRLDAP_TPD_ARRAY_INCREMENT * 5947c478bd9Sstevel@tonic-gate ( 1 + ( maxindex / PRLDAP_TPD_ARRAY_INCREMENT )); 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate /* increase the size of the data item array if necessary */ 5977c478bd9Sstevel@tonic-gate if ( count > tsdhdr->ptpdh_tpd_count ) { 5987c478bd9Sstevel@tonic-gate newdataitems = (PRLDAP_ErrorInfo *)PR_Calloc( count, sizeof( void * )); 5997c478bd9Sstevel@tonic-gate if ( newdataitems == NULL ) { 6007c478bd9Sstevel@tonic-gate return( NULL ); 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate if ( tsdhdr->ptpdh_dataitems != NULL ) { /* preserve old data */ 6037c478bd9Sstevel@tonic-gate memcpy( newdataitems, tsdhdr->ptpdh_dataitems, 6047c478bd9Sstevel@tonic-gate tsdhdr->ptpdh_tpd_count * sizeof( void * )); 6057c478bd9Sstevel@tonic-gate PR_Free( tsdhdr->ptpdh_dataitems ); 6067c478bd9Sstevel@tonic-gate } 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate tsdhdr->ptpdh_tpd_count = count; 6097c478bd9Sstevel@tonic-gate tsdhdr->ptpdh_dataitems = newdataitems; 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate return( tsdhdr ); 6137c478bd9Sstevel@tonic-gate } 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate 6167c478bd9Sstevel@tonic-gate /* 6177c478bd9Sstevel@tonic-gate * Function: prldap_tsd_destroy() 6187c478bd9Sstevel@tonic-gate * Description: Free a thread-private data array. Installed as an NSPR TPD 6197c478bd9Sstevel@tonic-gate * destructor function 6207c478bd9Sstevel@tonic-gate * Returns: nothing. 6217c478bd9Sstevel@tonic-gate * Note: this function assumes that each TPD item installed at the PRLDAP 6227c478bd9Sstevel@tonic-gate * level can be freed with a call to PR_Free(). 6237c478bd9Sstevel@tonic-gate */ 6247c478bd9Sstevel@tonic-gate static void 6257c478bd9Sstevel@tonic-gate prldap_tsd_destroy( void *priv ) 6267c478bd9Sstevel@tonic-gate { 6277c478bd9Sstevel@tonic-gate PRLDAP_TPDHeader *tsdhdr; 6287c478bd9Sstevel@tonic-gate int i; 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate tsdhdr = (PRLDAP_TPDHeader *)priv; 6317c478bd9Sstevel@tonic-gate if ( tsdhdr != NULL ) { 6327c478bd9Sstevel@tonic-gate if ( tsdhdr->ptpdh_dataitems != NULL ) { 6337c478bd9Sstevel@tonic-gate for ( i = 0; i < tsdhdr->ptpdh_tpd_count; ++i ) { 6347c478bd9Sstevel@tonic-gate if ( tsdhdr->ptpdh_dataitems[ i ] != NULL ) { 6357c478bd9Sstevel@tonic-gate PR_Free( tsdhdr->ptpdh_dataitems[ i ] ); 6367c478bd9Sstevel@tonic-gate tsdhdr->ptpdh_dataitems[ i ] = NULL; 6377c478bd9Sstevel@tonic-gate } 6387c478bd9Sstevel@tonic-gate } 6397c478bd9Sstevel@tonic-gate PR_Free( tsdhdr->ptpdh_dataitems ); 6407c478bd9Sstevel@tonic-gate tsdhdr->ptpdh_dataitems = NULL; 6417c478bd9Sstevel@tonic-gate } 6427c478bd9Sstevel@tonic-gate PR_Free( tsdhdr ); 6437c478bd9Sstevel@tonic-gate } 6447c478bd9Sstevel@tonic-gate } 6457c478bd9Sstevel@tonic-gate #endif 6467c478bd9Sstevel@tonic-gate 6477c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK 6487c478bd9Sstevel@tonic-gate #pragma init(prldap_nspr_init) 6497c478bd9Sstevel@tonic-gate static mutex_t nspr_init_lock = DEFAULTMUTEX; 6507c478bd9Sstevel@tonic-gate static int nspr_initialized = 0; 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate /* 6537c478bd9Sstevel@tonic-gate * Initialize NSPR once 6547c478bd9Sstevel@tonic-gate * 6557c478bd9Sstevel@tonic-gate */ 6567c478bd9Sstevel@tonic-gate void 6577c478bd9Sstevel@tonic-gate prldap_nspr_init(void) { 6587c478bd9Sstevel@tonic-gate struct sigaction action; 6597c478bd9Sstevel@tonic-gate 6607c478bd9Sstevel@tonic-gate /* 6617c478bd9Sstevel@tonic-gate * For performance reason, test it here first 6627c478bd9Sstevel@tonic-gate */ 6637c478bd9Sstevel@tonic-gate if (nspr_initialized != 0) 6647c478bd9Sstevel@tonic-gate return; 6657c478bd9Sstevel@tonic-gate 6667c478bd9Sstevel@tonic-gate (void) mutex_lock(&nspr_init_lock); 6677c478bd9Sstevel@tonic-gate /* Make sure PR_Init() is executed only once */ 6687c478bd9Sstevel@tonic-gate if (nspr_initialized == 0) { 6697c478bd9Sstevel@tonic-gate /* 6707c478bd9Sstevel@tonic-gate * PR_Init changes the signal handler of SIGPIPE to SIG_IGN. 6717c478bd9Sstevel@tonic-gate * Save the original and restore it after PR_Init. 6727c478bd9Sstevel@tonic-gate */ 6737c478bd9Sstevel@tonic-gate (void) sigaction(SIGPIPE, NULL, &action); 6747c478bd9Sstevel@tonic-gate 675*1d367f3fSth if (PR_Initialized() == PR_FALSE) { 6767c478bd9Sstevel@tonic-gate /* 677*1d367f3fSth * PR_Init() changes the current thread's 678*1d367f3fSth * priority. Save and restore the priority. 6797c478bd9Sstevel@tonic-gate */ 680*1d367f3fSth int priority; 681*1d367f3fSth (void) thr_getprio(thr_self(), &priority); 682*1d367f3fSth PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); 683*1d367f3fSth (void) thr_setprio(thr_self(), priority); 6847c478bd9Sstevel@tonic-gate } 685*1d367f3fSth nspr_initialized = 1; 6867c478bd9Sstevel@tonic-gate /* 6877c478bd9Sstevel@tonic-gate * Restore signal handling attributes of SIGPIPE 6887c478bd9Sstevel@tonic-gate */ 6897c478bd9Sstevel@tonic-gate (void) sigaction(SIGPIPE, &action, NULL); 6907c478bd9Sstevel@tonic-gate } 6917c478bd9Sstevel@tonic-gate (void) mutex_unlock(&nspr_init_lock); 6927c478bd9Sstevel@tonic-gate } 6937c478bd9Sstevel@tonic-gate #endif 694