int ldap_pvt_thread_initialize( void ) { int rc; static int init = 0; ldap_pvt_thread_rmutex_t rm; ldap_pvt_thread_t tid; /* we only get one shot at this */ if( init++ ) return -1; rc = ldap_int_thread_initialize(); if( rc ) return rc; #ifndef LDAP_THREAD_HAVE_TPOOL rc = ldap_int_thread_pool_startup(); if( rc ) return rc; #endif /* kludge to pull symbol definitions in */ ldap_pvt_thread_rmutex_init( &rm ); tid = ldap_pvt_thread_self(); ldap_pvt_thread_rmutex_lock( &rm, tid ); ldap_pvt_thread_rmutex_trylock( &rm, tid ); ldap_pvt_thread_rmutex_unlock( &rm, tid ); ldap_pvt_thread_rmutex_unlock( &rm, tid ); ldap_pvt_thread_rmutex_destroy( &rm ); return 0; }
int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rwlock ) { struct ldap_int_thread_rdwr_s *rw; assert( rwlock != NULL ); rw = *rwlock; assert( rw != NULL ); assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID ); if( rw->ltrw_valid != LDAP_PVT_THREAD_RDWR_VALID ) return LDAP_PVT_THREAD_EINVAL; ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex ); assert( rw->ltrw_w_active >= 0 ); assert( rw->ltrw_w_wait >= 0 ); assert( rw->ltrw_r_active >= 0 ); assert( rw->ltrw_r_wait >= 0 ); if ( rw->ltrw_w_active > 0 || rw->ltrw_r_active > 0 ) { ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex ); return LDAP_PVT_THREAD_EBUSY; } #ifdef LDAP_RDWR_DEBUG rw->ltrw_writer = ldap_pvt_thread_self(); #endif rw->ltrw_w_active++; ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex ); return 0; }
static unsigned long tlso_thread_self( void ) { /* FIXME: CRYPTO_set_id_callback only works when ldap_pvt_thread_t * is an integral type that fits in an unsigned long */ /* force an error if the ldap_pvt_thread_t type is too large */ enum { ok = sizeof( ldap_pvt_thread_t ) <= sizeof( unsigned long ) }; typedef struct { int dummy: ok ? 1 : -1; } Check[ok ? 1 : -1]; return (unsigned long) ldap_pvt_thread_self(); }
int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rwlock ) { struct ldap_int_thread_rdwr_s *rw; assert( rwlock != NULL ); rw = *rwlock; assert( rw != NULL ); assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID ); if( rw->ltrw_valid != LDAP_PVT_THREAD_RDWR_VALID ) return LDAP_PVT_THREAD_EINVAL; ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex ); rw->ltrw_r_active--; #ifdef LDAP_RDWR_DEBUG /* Remove us from the list of readers */ { ldap_pvt_thread_t self = ldap_pvt_thread_self(); int i, j; for( i = j = rw->ltrw_r_active; i >= 0; i--) { if (rw->ltrw_readers[i] == self) { rw->ltrw_readers[i] = rw->ltrw_readers[j]; rw->ltrw_readers[j] = 0; break; } } if( !rw->ltrw_more_readers ) assert( i >= 0 ); else if( j == 0 ) rw->ltrw_more_readers = 0; } #endif assert( rw->ltrw_w_active >= 0 ); assert( rw->ltrw_w_wait >= 0 ); assert( rw->ltrw_r_active >= 0 ); assert( rw->ltrw_r_wait >= 0 ); if (rw->ltrw_r_active == 0 && rw->ltrw_w_wait > 0 ) { ldap_pvt_thread_cond_signal( &rw->ltrw_write ); } ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex ); return 0; }
int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rwlock ) { struct ldap_int_thread_rdwr_s *rw; assert( rwlock != NULL ); rw = *rwlock; assert( rw != NULL ); assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID ); if( rw->ltrw_valid != LDAP_PVT_THREAD_RDWR_VALID ) return LDAP_PVT_THREAD_EINVAL; ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex ); assert( rw->ltrw_w_active >= 0 ); assert( rw->ltrw_w_wait >= 0 ); assert( rw->ltrw_r_active >= 0 ); assert( rw->ltrw_r_wait >= 0 ); if( rw->ltrw_w_active > 0 ) { /* writer is active */ rw->ltrw_r_wait++; do { ldap_pvt_thread_cond_wait( &rw->ltrw_read, &rw->ltrw_mutex ); } while( rw->ltrw_w_active > 0 ); rw->ltrw_r_wait--; assert( rw->ltrw_r_wait >= 0 ); } #ifdef LDAP_RDWR_DEBUG if( rw->ltrw_r_active < MAX_READERS ) rw->ltrw_readers[rw->ltrw_r_active] = ldap_pvt_thread_self(); else rw->ltrw_more_readers = 1; #endif rw->ltrw_r_active++; ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex ); return 0; }
int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rwlock ) { struct ldap_int_thread_rdwr_s *rw; assert( rwlock != NULL ); rw = *rwlock; assert( rw != NULL ); assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID ); if( rw->ltrw_valid != LDAP_PVT_THREAD_RDWR_VALID ) return LDAP_PVT_THREAD_EINVAL; ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex ); rw->ltrw_w_active--; assert( rw->ltrw_w_active >= 0 ); assert( rw->ltrw_w_wait >= 0 ); assert( rw->ltrw_r_active >= 0 ); assert( rw->ltrw_r_wait >= 0 ); if (rw->ltrw_r_wait > 0) { ldap_pvt_thread_cond_broadcast( &rw->ltrw_read ); } else if (rw->ltrw_w_wait > 0) { ldap_pvt_thread_cond_signal( &rw->ltrw_write ); } #ifdef LDAP_RDWR_DEBUG assert( rw->ltrw_writer == ldap_pvt_thread_self() ); rw->ltrw_writer = 0; #endif ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex ); return 0; }
int ldap_pvt_thread_mutex_recursive_trylock( ldap_pvt_thread_mutex_recursive_t *mp ) { return ldap_pvt_thread_rmutex_trylock( mp, ldap_pvt_thread_self() ); }
int ldap_pvt_thread_mutex_recursive_unlock( ldap_pvt_thread_mutex_recursive_t *mutex ) { return ldap_pvt_thread_rmutex_unlock( mutex, ldap_pvt_thread_self() ); }