/* * Function: prldap_return_map() * Description: return a thread-private data map to the pool of ones * available for re-use. */ static void prldap_return_map( PRLDAP_TPDMap *map ) { PRLDAP_ErrorInfo *eip; PR_Lock( prldap_map_mutex ); /* * Dispose of thread-private LDAP error information. Note that this * only disposes of the memory consumed on THIS thread, but that is * okay. See the comment in prldap_set_ld_error() for the reason why. */ if (( eip = (PRLDAP_ErrorInfo *)prldap_get_thread_private( map->prtm_index )) != NULL && prldap_set_thread_private( map->prtm_index, NULL ) == 0 ) { if ( eip->plei_matched != NULL ) { ldap_memfree( eip->plei_matched ); } if ( eip->plei_errmsg != NULL ) { ldap_memfree( eip->plei_errmsg ); } PR_Free( eip ); } /* mark map as available for re-use */ map->prtm_ld = NULL; PR_Unlock( prldap_map_mutex ); }
/* * Function: prldap_allocate_map() * Description: allocate a thread-private data map to use for a new * LDAP session handle. * Returns: a pointer to the TPD map or NULL if none available. */ static PRLDAP_TPDMap * prldap_allocate_map( LDAP *ld ) { PRLDAP_TPDMap *map, *prevmap; PR_Lock( prldap_map_mutex ); /* * first look for a map that is already allocated but free to be re-used */ prevmap = NULL; for ( map = prldap_map_list; map != NULL; map = map->prtm_next ) { if ( map->prtm_ld == NULL ) { break; } prevmap = map; } /* * if none we found (map == NULL), try to allocate a new one and add it * to the end of our global list. */ if ( map == NULL ) { PRUintn tpdindex; tpdindex = prldap_new_tpdindex(); map = (PRLDAP_TPDMap *)PR_Malloc( sizeof( PRLDAP_TPDMap )); if ( map != NULL ) { map->prtm_index = tpdindex; map->prtm_next = NULL; if ( prevmap == NULL ) { prldap_map_list = map; } else { prevmap->prtm_next = map; } } } if ( map != NULL ) { map->prtm_ld = ld; /* now marked as "in use" */ /* since we are reusing...reset */ /* to initial state */ (void)prldap_set_thread_private( map->prtm_index, NULL ); } PR_Unlock( prldap_map_mutex ); return( map ); }
static void prldap_set_ld_error( int err, char *matched, char *errmsg, void *errorarg ) { PRLDAP_TPDMap *map; PRLDAP_ErrorInfo *eip; if (( map = (PRLDAP_TPDMap *)errorarg ) != NULL ) { if (( eip = (PRLDAP_ErrorInfo *)prldap_get_thread_private( map->prtm_index )) == NULL ) { /* * Error info. has not yet been allocated for this thread. * Do so now. Note that we free this memory only for the * thread that calls prldap_thread_dispose_handle(), which * should be the one that called ldap_unbind() -- see * prldap_return_map(). Not freeing the memory used by * other threads is deemed acceptable since it will be * recycled and used by other LDAP sessions. All of the * thread-private memory is freed when a thread exits * (inside the prldap_tsd_destroy() function). */ eip = (PRLDAP_ErrorInfo *)PR_Calloc( 1, sizeof( PRLDAP_ErrorInfo )); if ( eip == NULL ) { return; /* punt */ } eip->plei_magic = PRLDAP_ERRORINFO_MAGIC; (void)prldap_set_thread_private( map->prtm_index, eip ); } eip->plei_lderrno = err; if ( eip->plei_matched != NULL ) { ldap_memfree( eip->plei_matched ); } eip->plei_matched = matched; if ( eip->plei_errmsg != NULL ) { ldap_memfree( eip->plei_errmsg ); } eip->plei_errmsg = errmsg; } }