One thing which is missing is pthread_once() to protect init functions. I'll commit one for pthreads and a default version, unless someone protests.
Then e.g. ldap_int_initialize() can use that - and if two threads call it at the same time, one will wait for the other's initialization to complete. The default would be something like the code below. Would also define LDAP_PVT_THREAD_MUTEX_INITIALIZER for the thread packages I know to define a static initializer for mutexes. typedef struct { volatile sig_atomic_t done; #ifndef LDAP_R_COMPILE #ifndef LDAP_PVT_THREAD_MUTEX_INITIALIZER volatile sig_atomic_t initialized; #endif ldap_pvt_thread_mutex_t mutex; #endif } ldap_pvt_thread_once_t; /* * Run a function only once per unique ONCE argument. If another * thread is running a function with the same ONCE value, wait for it. * The function cannot be called recursively with the same ONCE value. * Threads can deadlock if A() calls B() once and B() calls A() once. * * This default version is not quite safe: It can call a function for * ONCE twice if the _first_ calls to ldap_pvt_thread_once() happen * in parallell before ldap_pvt_thread_initialize() has been called. */ void ldap_pvt_thread_once( ldap_pvt_thread_once_t *once, void (*func)( void ) ) { if( !once->done ) { #ifdef LDAP_R_COMPILE # ifndef LDAP_PVT_THREAD_MUTEX_INITIALIZER /* Initialize ldap_pvt_thread_once(). */ static volatile sig_atomic_t once_init_done; static ldap_pvt_thread_mutex_t once_init_mutex; if( !once_init_done ) { ldap_pvt_thread_mutex_init( &once_init_mutex ); once_init_done = 1; } /* Initialize the ONCE parameter if necessary. */ ldap_pvt_thread_mutex_lock( &once_init_mutex ); if( !once->initialized ) { ldap_pvt_thread_mutex_init( &once->mutex ); once->initialized = 1; } ldap_pvt_thread_mutex_unlock( &once_init_mutex ); # endif /* !LDAP_PVT_THREAD_MUTEX_INITIALIZER */ ldap_pvt_thread_mutex_lock( &once->mutex ); if( !once->done ) { func(); once->done = 1; } ldap_pvt_thread_mutex_unlock( &once->mutex ); #else /* !LDAP_R_COMPILE */ func(); once->done = 1; #endif /* !LDAP_R_COMPILE */ } } -- Hallvard