Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions | Variables
ldappr-threads.c File Reference
#include "ldappr-int.h"

Go to the source code of this file.

Classes

struct  prldap_errorinfo
struct  prldap_tpd_header
struct  prldap_tpd_map

Defines

#define PRLDAP_TPD_ARRAY_INCREMENT   10

Typedefs

typedef struct prldap_errorinfo PRLDAP_ErrorInfo
typedef struct prldap_tpd_header PRLDAP_TPDHeader
typedef struct prldap_tpd_map PRLDAP_TPDMap

Functions

static void prldap_set_ld_error (int err, char *matched, char *errmsg, void *errorarg)
static int prldap_get_ld_error (char **matchedp, char **errmsgp, void *errorarg)
static voidprldap_mutex_alloc (void)
static void prldap_mutex_free (void *mutex)
static int prldap_mutex_lock (void *mutex)
static int prldap_mutex_unlock (void *mutex)
static voidprldap_get_thread_id (void)
static PRStatus prldap_init_tpd (void)
static PRLDAP_TPDMapprldap_allocate_map (LDAP *ld)
static void prldap_return_map (PRLDAP_TPDMap *map)
static PRUintn prldap_new_tpdindex (void)
static int prldap_set_thread_private (PRInt32 tpdindex, void *priv)
static voidprldap_get_thread_private (PRInt32 tpdindex)
static PRLDAP_TPDHeaderprldap_tsd_realloc (PRLDAP_TPDHeader *tsdhdr, int maxindex)
static void prldap_tsd_destroy (void *priv)
int prldap_install_thread_functions (LDAP *ld, int shared)
int prldap_thread_new_handle (LDAP *ld, void *sessionarg)
void prldap_thread_dispose_handle (LDAP *ld, void *sessionarg)

Variables

static PRLDAP_TPDMapprldap_map_list = NULL
static PRLockprldap_map_mutex = NULL
static PRInt32 prldap_tpd_maxindex = -1
static PRUintn prldap_tpdindex = 0
static PRCallOnceType prldap_callonce_init_tpd = { 0, 0, 0 }

Class Documentation

struct prldap_errorinfo

Definition at line 60 of file ldappr-threads.c.

Collaboration diagram for prldap_errorinfo:
Class Members
char * plei_errmsg
int plei_lderrno
char * plei_matched
struct prldap_tpd_header

Definition at line 71 of file ldappr-threads.c.

Collaboration diagram for prldap_tpd_header:
Class Members
void ** ptpdh_dataitems
int ptpdh_tpd_count
struct prldap_tpd_map

Definition at line 81 of file ldappr-threads.c.

Collaboration diagram for prldap_tpd_map:
Class Members
PRUintn prtm_index
LDAP * prtm_ld
struct prldap_tpd_map * prtm_next

Define Documentation

Definition at line 52 of file ldappr-threads.c.


Typedef Documentation

typedef struct prldap_tpd_map PRLDAP_TPDMap

Function Documentation

static PRLDAP_TPDMap * prldap_allocate_map ( LDAP *  ld) [static]

Definition at line 384 of file ldappr-threads.c.

{
    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 );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prldap_get_ld_error ( char **  matchedp,
char **  errmsgp,
void errorarg 
) [static]

Definition at line 250 of file ldappr-threads.c.

{
    PRLDAP_TPDMap    *map;
    PRLDAP_ErrorInfo *eip;

    if (( map = (PRLDAP_TPDMap *)errorarg ) != NULL && ( eip =
           (PRLDAP_ErrorInfo *)prldap_get_thread_private(
           map->prtm_index )) != NULL ) {
       if ( matchedp != NULL ) {
           *matchedp = eip->plei_matched;
       }
       if ( errmsgp != NULL ) {
           *errmsgp = eip->plei_errmsg;
       }
       return( eip->plei_lderrno );
    } else {
       if ( matchedp != NULL ) {
           *matchedp = NULL;
       }
       if ( errmsgp != NULL ) {
           *errmsgp = NULL;
       }
       return( LDAP_LOCAL_ERROR ); /* punt */
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void * prldap_get_thread_id ( void  ) [static]

Definition at line 243 of file ldappr-threads.c.

{
    return( (void *)PR_GetCurrentThread());
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void * prldap_get_thread_private ( PRInt32  tpdindex) [static]

Definition at line 520 of file ldappr-threads.c.

{
    PRLDAP_TPDHeader *tsdhdr;

    tsdhdr = (PRLDAP_TPDHeader *)PR_GetThreadPrivate( prldap_tpdindex );
    if ( tsdhdr == NULL ) {
       return( NULL );      /* no thread private data */
    }

    if ( tpdindex >= tsdhdr->ptpdh_tpd_count
              || tsdhdr->ptpdh_dataitems == NULL ) {
       return( NULL );      /* fewer data items than requested index */
    }

    return( tsdhdr->ptpdh_dataitems[ tpdindex ] );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus prldap_init_tpd ( void  ) [static]

Definition at line 364 of file ldappr-threads.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int prldap_install_thread_functions ( LDAP *  ld,
int  shared 
)

Definition at line 155 of file ldappr-threads.c.

{
    struct ldap_thread_fns         tfns;
    struct ldap_extra_thread_fns   xtfns;

    if ( PR_CallOnce( &prldap_callonce_init_tpd, prldap_init_tpd )
              != PR_SUCCESS ) {
       ldap_set_lderrno( ld, LDAP_LOCAL_ERROR, NULL, NULL );
       return( -1 );
    }

    /* set thread function pointers */
    memset( &tfns, '\0', sizeof(struct ldap_thread_fns) );
    tfns.ltf_get_errno = prldap_get_system_errno;
    tfns.ltf_set_errno = prldap_set_system_errno;
    if ( shared ) {
       tfns.ltf_mutex_alloc = prldap_mutex_alloc;
       tfns.ltf_mutex_free = prldap_mutex_free;
       tfns.ltf_mutex_lock = prldap_mutex_lock;
       tfns.ltf_mutex_unlock = prldap_mutex_unlock;
       tfns.ltf_get_lderrno = prldap_get_ld_error;
       tfns.ltf_set_lderrno = prldap_set_ld_error;
       if ( ld != NULL ) {
           /*
            * If this is a real ld (i.e., we are not setting the global
            * defaults) allocate thread private data for error information.
            * If ld is NULL we do not do this here but it is done in
            * prldap_thread_new_handle().
            */
           if (( tfns.ltf_lderrno_arg = (void *)prldap_allocate_map( ld ))
                  == NULL ) {
              return( -1 );
           }
       }
    }

    if ( ldap_set_option( ld, LDAP_OPT_THREAD_FN_PTRS,
           (void *)&tfns ) != 0 ) {
       prldap_return_map( (PRLDAP_TPDMap *)tfns.ltf_lderrno_arg );
       return( -1 );
    }

    /* set extended thread function pointers */
    memset( &xtfns, '\0', sizeof(struct ldap_extra_thread_fns) );
    xtfns.ltf_threadid_fn = prldap_get_thread_id;
    if ( ldap_set_option( ld, LDAP_OPT_EXTRA_THREAD_FN_PTRS,
           (void *)&xtfns ) != 0 ) {
       return( -1 );
    }

    return( 0 );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void * prldap_mutex_alloc ( void  ) [static]

Definition at line 210 of file ldappr-threads.c.

{
    return( (void *)PR_NewLock());
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void prldap_mutex_free ( void mutex) [static]

Definition at line 217 of file ldappr-threads.c.

{
    PR_DestroyLock( (PRLock *)mutex );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prldap_mutex_lock ( void mutex) [static]

Definition at line 224 of file ldappr-threads.c.

{
    PR_Lock( (PRLock *)mutex );
    return( 0 );
}

Here is the caller graph for this function:

static int prldap_mutex_unlock ( void mutex) [static]

Definition at line 232 of file ldappr-threads.c.

{
    if ( PR_Unlock( (PRLock *)mutex ) == PR_FAILURE ) {
       return( -1 );
    }

    return( 0 );
}

Here is the caller graph for this function:

static PRUintn prldap_new_tpdindex ( void  ) [static]

Definition at line 477 of file ldappr-threads.c.

{
    PRUintn   tpdindex;

    tpdindex = (PRUintn)PR_AtomicIncrement( &prldap_tpd_maxindex );
    return( tpdindex );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void prldap_return_map ( PRLDAP_TPDMap map) [static]

Definition at line 440 of file ldappr-threads.c.

{
    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 );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void prldap_set_ld_error ( int  err,
char *  matched,
char *  errmsg,
void errorarg 
) [static]

Definition at line 278 of file ldappr-threads.c.

{
    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 */
           }
           (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;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prldap_set_thread_private ( PRInt32  tpdindex,
void priv 
) [static]

Definition at line 492 of file ldappr-threads.c.

{
    PRLDAP_TPDHeader *tsdhdr;

    if ( tpdindex > prldap_tpd_maxindex ) {
       return( -1 ); /* bad index */ 
    }

    tsdhdr = (PRLDAP_TPDHeader *)PR_GetThreadPrivate( prldap_tpdindex );
    if ( tsdhdr == NULL || tpdindex >= tsdhdr->ptpdh_tpd_count ) {
       tsdhdr = prldap_tsd_realloc( tsdhdr, tpdindex );
       if ( tsdhdr == NULL ) {
           return( -1 );    /* realloc failed */
       }
    }

    tsdhdr->ptpdh_dataitems[ tpdindex ] = priv;
    return( 0 );
}

Here is the call graph for this function:

Here is the caller graph for this function:

void prldap_thread_dispose_handle ( LDAP *  ld,
void sessionarg 
)

Definition at line 351 of file ldappr-threads.c.

{
    struct ldap_thread_fns  tfns;

    if ( ldap_get_option( ld, LDAP_OPT_THREAD_FN_PTRS,
           (void *)&tfns ) == 0 &&
           tfns.ltf_lderrno_arg != NULL ) {
       prldap_return_map( (PRLDAP_TPDMap *)tfns.ltf_lderrno_arg );
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int prldap_thread_new_handle ( LDAP *  ld,
void sessionarg 
)

Definition at line 326 of file ldappr-threads.c.

{
    struct ldap_thread_fns  tfns;

    if ( ldap_get_option( ld, LDAP_OPT_THREAD_FN_PTRS, (void *)&tfns ) != 0 ) {
       return( LDAP_LOCAL_ERROR );
    }

    if ( tfns.ltf_lderrno_arg == NULL && tfns.ltf_get_lderrno != NULL ) {
       if (( tfns.ltf_lderrno_arg = (void *)prldap_allocate_map( ld )) == NULL
              || ldap_set_option( ld, LDAP_OPT_THREAD_FN_PTRS,
              (void *)&tfns ) != 0 ) {
           return( LDAP_LOCAL_ERROR );
       }
    }

    return( LDAP_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void prldap_tsd_destroy ( void priv) [static]

Definition at line 594 of file ldappr-threads.c.

{
    PRLDAP_TPDHeader *tsdhdr;
    int                     i;

    tsdhdr = (PRLDAP_TPDHeader *)priv;
    if ( tsdhdr != NULL ) {
       if ( tsdhdr->ptpdh_dataitems != NULL ) {
           for ( i = 0; i < tsdhdr->ptpdh_tpd_count; ++i ) {
              if ( tsdhdr->ptpdh_dataitems[ i ] != NULL ) {
                  PR_Free( tsdhdr->ptpdh_dataitems[ i ] );
                  tsdhdr->ptpdh_dataitems[ i ] = NULL;
              }
           }
           PR_Free( tsdhdr->ptpdh_dataitems );
           tsdhdr->ptpdh_dataitems = NULL;
       }
       PR_Free( tsdhdr );
    }
}

Here is the caller graph for this function:

static PRLDAP_TPDHeader * prldap_tsd_realloc ( PRLDAP_TPDHeader tsdhdr,
int  maxindex 
) [static]

Definition at line 545 of file ldappr-threads.c.

{
    void      *newdataitems = NULL;
    int              count;

    if ( tsdhdr == NULL ) {
       /* allocate a new thread private data header */
       if (( tsdhdr = PR_Calloc( 1, sizeof( PRLDAP_TPDHeader ))) == NULL ) {
           return( NULL );
       }
       (void)PR_SetThreadPrivate( prldap_tpdindex, tsdhdr );
    }

    /*
     * Make the size of the new array the next highest multiple of
     * the array increment value that is greater than maxindex.
     */
    count = PRLDAP_TPD_ARRAY_INCREMENT *
              ( 1 + ( maxindex / PRLDAP_TPD_ARRAY_INCREMENT ));

    /* increase the size of the data item array if necessary */
    if ( count > tsdhdr->ptpdh_tpd_count  ) {
       newdataitems = (PRLDAP_ErrorInfo *)PR_Calloc( count, sizeof( void * ));
       if ( newdataitems == NULL ) {
           return( NULL );
       }
       if ( tsdhdr->ptpdh_dataitems != NULL ) {  /* preserve old data */
           memcpy( newdataitems, tsdhdr->ptpdh_dataitems,
                     tsdhdr->ptpdh_tpd_count * sizeof( void * ));
           PR_Free( tsdhdr->ptpdh_dataitems );
       }

       tsdhdr->ptpdh_tpd_count = count;
       tsdhdr->ptpdh_dataitems = newdataitems;
    }

    return( tsdhdr );
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

PRCallOnceType prldap_callonce_init_tpd = { 0, 0, 0 } [static]

Definition at line 122 of file ldappr-threads.c.

Definition at line 97 of file ldappr-threads.c.

Definition at line 103 of file ldappr-threads.c.

Definition at line 109 of file ldappr-threads.c.

PRUintn prldap_tpdindex = 0 [static]

Definition at line 116 of file ldappr-threads.c.