From ec426532b2cca95330566b1941795dac7e03bb57 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Tue, 13 Jun 2000 02:42:13 +0000 Subject: [PATCH] Reworked thread code to better support thread-library specific r/w locks and thread pools. Hide internal structures (using pthread'ish technics). Place common code in threads.c. Move no-thread code to thr_stub.c. Move thread pool code to tpool.c. Removed setconcurrency call from initializer, added 'concurrency' directive to slapd. Tested code under pthreads, pth, and no-threads. --- doc/man/man5/slapd.conf.5 | 4 + include/ldap_int_thread.h | 100 +----- include/ldap_pvt_thread.h | 41 +-- libraries/libldap_r/Makefile.in | 12 +- libraries/libldap_r/rdwr.c | 97 +++++- libraries/libldap_r/thr_cthreads.c | 34 +- libraries/libldap_r/thr_lwp.c | 36 +- libraries/libldap_r/thr_nt.c | 36 +- libraries/libldap_r/thr_posix.c | 59 ++-- libraries/libldap_r/thr_pth.c | 40 ++- libraries/libldap_r/thr_sleep.c | 57 --- libraries/libldap_r/thr_stub.c | 70 +++- libraries/libldap_r/thr_thr.c | 45 +-- libraries/libldap_r/threads.c | 534 +++-------------------------- libraries/libldap_r/tpool.c | 396 +++++++++++++++++++++ servers/slapd/backend.c | 14 - servers/slapd/config.c | 21 ++ servers/slapd/connection.c | 3 +- servers/slapd/daemon.c | 6 +- servers/slapd/init.c | 4 +- servers/slapd/monitor.c | 3 +- 21 files changed, 768 insertions(+), 844 deletions(-) delete mode 100644 libraries/libldap_r/thr_sleep.c create mode 100644 libraries/libldap_r/tpool.c diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index 6801af0c89..4016f9df55 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -103,6 +103,10 @@ SubstringAssertion NISnetgrouptriple Bootparameter .RE .RE .TP +.B concurrency +Specify a desired level of concurrency. Provided to the underlying +thread system as a hint. The default is not to provdide any hint. +.TP .B defaultaccess { none | auth | compare | search | read | write } Specify the default access level to grant requestors when diff --git a/include/ldap_int_thread.h b/include/ldap_int_thread.h index 034f44e4d1..f89afb55a4 100644 --- a/include/ldap_int_thread.h +++ b/include/ldap_int_thread.h @@ -13,8 +13,6 @@ #ifndef _LDAP_INT_THREAD_H #define _LDAP_INT_THREAD_H -#include "ldap_cdefs.h" - #if defined( HAVE_PTHREADS ) /********************************** * * @@ -41,12 +39,12 @@ typedef pthread_cond_t ldap_int_thread_cond_t; #if defined( HAVE_PTHREAD_GETCONCURRENCY ) || \ defined( HAVE_THR_GETCONCURRENCY ) -#define HAVE_GETCONCURRENCY 1 +#define LDAP_THREAD_HAVE_GETCONCURRENCY 1 #endif #if defined( HAVE_PTHREAD_SETCONCURRENCY ) || \ defined( HAVE_THR_SETCONCURRENCY ) -#define HAVE_SETCONCURRENCY 1 +#define LDAP_THREAD_HAVE_SETCONCURRENCY 1 #endif #if 0 && defined( HAVE_PTHREAD_RWLOCK_DESTROY ) @@ -96,7 +94,6 @@ typedef pth_rwlock_t ldap_pvt_thread_rdwr_t; LDAP_END_DECL - #elif defined( HAVE_THR ) /******************************************** * * @@ -116,10 +113,10 @@ typedef cond_t ldap_int_thread_cond_t; #define HAVE_REENTRANT_FUNCTIONS 1 #ifdef HAVE_THR_GETCONCURRENCY -#define HAVE_GETCONCURRENCY 1 +#define LDAP_THREAD_HAVE_GETCONCURRENCY 1 #endif #ifdef HAVE_THR_SETCONCURRENCY -#define HAVE_SETCONCURRENCY 1 +#define LDAP_THREAD_HAVE_SETCONCURRENCY 1 #endif LDAP_END_DECL @@ -133,6 +130,7 @@ LDAP_END_DECL #include #include +#define LDAP_THREAD_HAVE_SLEEP 1 LDAP_BEGIN_DECL @@ -150,11 +148,11 @@ LDAP_END_DECL #elif defined(HAVE_NT_THREADS) -LDAP_BEGIN_DECL - #include #include +LDAP_BEGIN_DECL + typedef unsigned long ldap_int_thread_t; typedef HANDLE ldap_int_thread_mutex_t; typedef HANDLE ldap_int_thread_cond_t; @@ -170,96 +168,34 @@ LDAP_END_DECL * * ***********************************/ -LDAP_BEGIN_DECL - #ifndef NO_THREADS #define NO_THREADS 1 #endif +LDAP_BEGIN_DECL + typedef int ldap_int_thread_t; typedef int ldap_int_thread_mutex_t; typedef int ldap_int_thread_cond_t; +#define LDAP_THREAD_HAVE_TPOOL 1 +typedef int ldap_int_thread_pool_t; + LDAP_END_DECL #endif /* no threads support */ LDAP_BEGIN_DECL -LIBLDAP_F( int ) -ldap_int_thread_initialize LDAP_P(( void )); - -LIBLDAP_F( int ) -ldap_int_thread_destroy LDAP_P(( void )); - -LIBLDAP_F( unsigned int ) -ldap_int_thread_sleep LDAP_P(( unsigned int s )); - -#ifdef HAVE_GETCONCURRENCY -LIBLDAP_F( int ) -ldap_int_thread_get_concurrency LDAP_P(( void )); -#endif +LIBLDAP_F(int) ldap_int_thread_initialize LDAP_P(( void )); +LIBLDAP_F(int) ldap_int_thread_destroy LDAP_P(( void )); +LIBLDAP_F(int) ldap_int_thread_pool_startup ( void ); +LIBLDAP_F(int) ldap_int_thread_pool_shutdown ( void ); -#ifdef HAVE_SETCONCURRENCY -# ifndef LDAP_THREAD_CONCURRENCY - /* three concurrent threads should be enough */ -# define LDAP_THREAD_CONCURRENCY 3 -# endif -LIBLDAP_F( int ) -ldap_int_thread_set_concurrency LDAP_P(( int )); +#ifndef LDAP_THREAD_HAVE_TPOOL +typedef struct ldap_int_thread_pool_s * ldap_int_thread_pool_t; #endif -LIBLDAP_F( int ) -ldap_int_thread_create LDAP_P(( - ldap_int_thread_t * thread, - int detach, - void *(*start_routine)( void * ), - void *arg)); - -LIBLDAP_F( void ) -ldap_int_thread_exit LDAP_P(( void *retval )); - -LIBLDAP_F( int ) -ldap_int_thread_join LDAP_P(( ldap_int_thread_t thread, void **status )); - -LIBLDAP_F( int ) -ldap_int_thread_kill LDAP_P(( ldap_int_thread_t thread, int signo )); - -LIBLDAP_F( int ) -ldap_int_thread_yield LDAP_P(( void )); - -LIBLDAP_F( int ) -ldap_int_thread_cond_init LDAP_P(( ldap_int_thread_cond_t *cond )); - -LIBLDAP_F( int ) -ldap_int_thread_cond_destroy LDAP_P(( ldap_int_thread_cond_t *cond )); - -LIBLDAP_F( int ) -ldap_int_thread_cond_signal LDAP_P(( ldap_int_thread_cond_t *cond )); - -LIBLDAP_F( int ) -ldap_int_thread_cond_broadcast LDAP_P(( ldap_int_thread_cond_t *cond )); - -LIBLDAP_F( int ) -ldap_int_thread_cond_wait LDAP_P(( - ldap_int_thread_cond_t *cond, - ldap_int_thread_mutex_t *mutex )); - -LIBLDAP_F( int ) -ldap_int_thread_mutex_init LDAP_P(( ldap_int_thread_mutex_t *mutex )); - -LIBLDAP_F( int ) -ldap_int_thread_mutex_destroy LDAP_P(( ldap_int_thread_mutex_t *mutex )); - -LIBLDAP_F( int ) -ldap_int_thread_mutex_lock LDAP_P(( ldap_int_thread_mutex_t *mutex )); - -LIBLDAP_F( int ) -ldap_int_thread_mutex_trylock LDAP_P(( ldap_int_thread_mutex_t *mutex )); - -LIBLDAP_F( int ) -ldap_int_thread_mutex_unlock LDAP_P(( ldap_int_thread_mutex_t *mutex )); - LDAP_END_DECL #endif /* _LDAP_INT_THREAD_H */ diff --git a/include/ldap_pvt_thread.h b/include/ldap_pvt_thread.h index 7d818c4b09..23df121b1e 100644 --- a/include/ldap_pvt_thread.h +++ b/include/ldap_pvt_thread.h @@ -22,7 +22,6 @@ typedef ldap_int_thread_t ldap_pvt_thread_t; typedef ldap_int_thread_mutex_t ldap_pvt_thread_mutex_t; typedef ldap_int_thread_cond_t ldap_pvt_thread_cond_t; - LIBLDAP_F( int ) ldap_pvt_thread_initialize LDAP_P(( void )); @@ -35,10 +34,6 @@ ldap_pvt_thread_sleep LDAP_P(( unsigned int s )); LIBLDAP_F( int ) ldap_pvt_thread_get_concurrency LDAP_P(( void )); -#ifndef LDAP_THREAD_CONCURRENCY - /* three concurrent threads should be enough */ -#define LDAP_THREAD_CONCURRENCY 3 -#endif LIBLDAP_F( int ) ldap_pvt_thread_set_concurrency LDAP_P(( int )); @@ -97,17 +92,7 @@ LIBLDAP_F( int ) ldap_pvt_thread_mutex_unlock LDAP_P(( ldap_pvt_thread_mutex_t *mutex )); #ifndef LDAP_THREAD_HAVE_RDWR -typedef struct ldap_pvt_thread_rdwr_var { - ldap_pvt_thread_mutex_t ltrw_mutex; - ldap_pvt_thread_cond_t ltrw_read; /* wait for read */ - ldap_pvt_thread_cond_t ltrw_write; /* wait for write */ - int ltrw_valid; -#define LDAP_PVT_THREAD_RDWR_VALID 0x0bad - int ltrw_r_active; - int ltrw_w_active; - int ltrw_r_wait; - int ltrw_w_wait; -} ldap_pvt_thread_rdwr_t; +typedef struct ldap_int_thread_rdwr_s * ldap_pvt_thread_rdwr_t; #endif LIBLDAP_F( int ) @@ -148,30 +133,28 @@ ldap_pvt_thread_rdwr_active LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp)); #define LDAP_PVT_THREAD_EINVAL EINVAL #define LDAP_PVT_THREAD_EBUSY EINVAL - -typedef struct t_ldap_pvt_thread_pool *ldap_pvt_thread_pool_t; - +typedef ldap_int_thread_pool_t ldap_pvt_thread_pool_t; LIBLDAP_F( int ) -ldap_pvt_thread_pool_initialize LDAP_P(( - ldap_pvt_thread_pool_t *pool_out, - int max_concurrency, - int max_pending )); +ldap_pvt_thread_pool_init LDAP_P(( + ldap_pvt_thread_pool_t *pool_out, + int max_concurrency, + int max_pending )); LIBLDAP_F( int ) ldap_pvt_thread_pool_submit LDAP_P(( - ldap_pvt_thread_pool_t pool, - void *(*start_routine)( void * ), - void *arg )); + ldap_pvt_thread_pool_t *pool, + void *(*start_routine)( void * ), + void *arg )); LIBLDAP_F( int ) ldap_pvt_thread_pool_backload LDAP_P(( - ldap_pvt_thread_pool_t pool )); + ldap_pvt_thread_pool_t *pool )); LIBLDAP_F( int ) ldap_pvt_thread_pool_destroy LDAP_P(( - ldap_pvt_thread_pool_t pool, - int run_pending )); + ldap_pvt_thread_pool_t *pool, + int run_pending )); LDAP_END_DECL diff --git a/libraries/libldap_r/Makefile.in b/libraries/libldap_r/Makefile.in index 616996ba2d..a95fec2275 100644 --- a/libraries/libldap_r/Makefile.in +++ b/libraries/libldap_r/Makefile.in @@ -20,9 +20,13 @@ XXSRCS = apitest.c test.c tmpltest.c extended.c \ init.c options.c print.c string.c util-int.c schema.c \ charray.c tls.c dn.c os-local.c dnssrv.c \ utf-8.c -SRCS = thr_posix.c thr_cthreads.c thr_thr.c thr_lwp.c thr_nt.c \ - thr_pth.c thr_sleep.c thr_stub.c rdwr.c threads.c -OBJS = extended.lo \ +SRCS = threads.c rdwr.c tpool.c \ + thr_posix.c thr_cthreads.c thr_thr.c thr_lwp.c thr_nt.c \ + thr_pth.c thr_stub.c +OBJS = threads.lo rdwr.lo tpool.lo \ + thr_posix.lo thr_cthreads.lo thr_thr.lo thr_lwp.lo thr_nt.lo \ + thr_pth.lo thr_stub.lo \ + extended.lo \ bind.lo controls.lo open.lo result.lo error.lo compare.lo search.lo \ modify.lo add.lo modrdn.lo delete.lo abandon.lo ufn.lo cache.lo \ getfilter.lo sasl.lo sbind.lo kbind.lo unbind.lo friendly.lo cldap.lo \ @@ -30,8 +34,6 @@ OBJS = extended.lo \ getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \ request.lo os-ip.lo url.lo sortctrl.lo vlvctrl.lo \ init.lo options.lo print.lo string.lo util-int.lo schema.lo \ - thr_posix.lo thr_cthreads.lo thr_thr.lo thr_lwp.lo thr_nt.lo \ - thr_pth.lo thr_sleep.lo thr_stub.lo rdwr.lo threads.lo \ charray.lo tls.lo dn.lo os-local.lo dnssrv.lo \ utf-8.lo diff --git a/libraries/libldap_r/rdwr.c b/libraries/libldap_r/rdwr.c index 5e04a43a62..6a43f66a18 100644 --- a/libraries/libldap_r/rdwr.c +++ b/libraries/libldap_r/rdwr.c @@ -19,7 +19,9 @@ #include #include +#include +#include "ldap-int.h" #include "ldap_pvt_thread.h" /* @@ -29,12 +31,27 @@ */ #ifndef LDAP_THREAD_HAVE_RDWR +struct ldap_int_thread_rdwr_s { + ldap_pvt_thread_mutex_t ltrw_mutex; + ldap_pvt_thread_cond_t ltrw_read; /* wait for read */ + ldap_pvt_thread_cond_t ltrw_write; /* wait for write */ + int ltrw_valid; +#define LDAP_PVT_THREAD_RDWR_VALID 0x0bad + int ltrw_r_active; + int ltrw_w_active; + int ltrw_r_wait; + int ltrw_w_wait; +}; + int -ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw ) +ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rwlock ) { - assert( rw != NULL ); + struct ldap_int_thread_rdwr_s *rw; + + assert( rwlock != NULL ); - memset( rw, '\0', sizeof(ldap_pvt_thread_rdwr_t) ); + rw = (struct ldap_int_thread_rdwr_s *) LDAP_CALLOC( 1, + sizeof( struct ldap_int_thread_rdwr_s ) ); /* we should check return results */ ldap_pvt_thread_mutex_init( &rw->ltrw_mutex ); @@ -42,12 +59,19 @@ ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw ) ldap_pvt_thread_cond_init( &rw->ltrw_write ); rw->ltrw_valid = LDAP_PVT_THREAD_RDWR_VALID; + + *rwlock = rw; return 0; } int -ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw ) +ldap_pvt_thread_rdwr_destroy( 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 ); @@ -76,11 +100,18 @@ ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw ) ldap_pvt_thread_cond_destroy( &rw->ltrw_read ); ldap_pvt_thread_cond_destroy( &rw->ltrw_write ); + LDAP_FREE(rw); + *rwlock = NULL; return 0; } -int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw ) +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 ); @@ -109,8 +140,13 @@ int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw ) return 0; } -int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw ) +int ldap_pvt_thread_rdwr_rtrylock( 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 ); @@ -131,8 +167,13 @@ int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw ) return 0; } -int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw ) +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 ); @@ -152,8 +193,13 @@ int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw ) return 0; } -int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw ) +int ldap_pvt_thread_rdwr_wlock( 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 ); @@ -180,8 +226,13 @@ int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw ) return 0; } -int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw ) +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 ); @@ -202,8 +253,13 @@ int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw ) return 0; } -int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw ) +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 ); @@ -238,24 +294,39 @@ int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw ) * a lock are caught. */ -int ldap_pvt_thread_rdwr_readers(ldap_pvt_thread_rdwr_t *rw) +int ldap_pvt_thread_rdwr_readers(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 ); return( rw->ltrw_r_active ); } -int ldap_pvt_thread_rdwr_writers(ldap_pvt_thread_rdwr_t *rw) +int ldap_pvt_thread_rdwr_writers(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 ); return( rw->ltrw_w_active ); } -int ldap_pvt_thread_rdwr_active(ldap_pvt_thread_rdwr_t *rw) +int ldap_pvt_thread_rdwr_active(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 ); diff --git a/libraries/libldap_r/thr_cthreads.c b/libraries/libldap_r/thr_cthreads.c index 807ecde35e..8e9049c7b1 100644 --- a/libraries/libldap_r/thr_cthreads.c +++ b/libraries/libldap_r/thr_cthreads.c @@ -14,7 +14,7 @@ #include "portable.h" #if defined( HAVE_MACH_CTHREADS ) -#include "ldap_int_thread.h" +#include "ldap_pvt_thread.h" /*********************************************************************** * * @@ -36,7 +36,7 @@ ldap_int_thread_destroy( void ) } int -ldap_int_thread_create( ldap_int_thread_t * thread, +ldap_pvt_thread_create( ldap_pvt_thread_t * thread, int detach, void *(*start_routine)( void *), void *arg) { @@ -45,13 +45,13 @@ ldap_int_thread_create( ldap_int_thread_t * thread, } void -ldap_int_thread_exit( void *retval ) +ldap_pvt_thread_exit( void *retval ) { cthread_exit( (any_t) retval ); } int -ldap_int_thread_join( ldap_int_thread_t thread, void **thread_return ) +ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return ) { void *status; status = (void *) cthread_join ( thread ); @@ -63,56 +63,56 @@ ldap_int_thread_join( ldap_int_thread_t thread, void **thread_return ) } int -ldap_int_thread_kill( ldap_int_thread_t thread, int signo ) +ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo ) { return 0; } int -ldap_int_thread_yield( void ) +ldap_pvt_thread_yield( void ) { cthread_yield(); return 0; } int -ldap_int_thread_cond_init( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond ) { condition_init( cond ); return( 0 ); } int -ldap_int_thread_cond_destroy( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cond ) { condition_clear( cond ); return( 0 ); } int -ldap_int_thread_cond_signal( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond ) { condition_signal( cond ); return( 0 ); } int -ldap_int_thread_cond_broadcast( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond ) { condition_broadcast( cond ); return( 0 ); } int -ldap_int_thread_cond_wait( ldap_int_thread_cond_t *cond, - ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, + ldap_pvt_thread_mutex_t *mutex ) { condition_wait( cond, mutex ); return( 0 ); } int -ldap_int_thread_mutex_init( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex ) { mutex_init( mutex ); mutex->name = NULL; @@ -120,28 +120,28 @@ ldap_int_thread_mutex_init( ldap_int_thread_mutex_t *mutex ) } int -ldap_int_thread_mutex_destroy( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) { mutex_clear( mutex ); return ( 0 ); } int -ldap_int_thread_mutex_lock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex ) { mutex_lock( mutex ); return ( 0 ); } int -ldap_int_thread_mutex_unlock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) { mutex_unlock( mutex ); return ( 0 ); } int -ldap_int_thread_mutex_trylock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex ) { return mutex_try_lock( mutex ); } diff --git a/libraries/libldap_r/thr_lwp.c b/libraries/libldap_r/thr_lwp.c index bdb00e3326..69ddd72f00 100644 --- a/libraries/libldap_r/thr_lwp.c +++ b/libraries/libldap_r/thr_lwp.c @@ -35,7 +35,7 @@ #include "ldap-int.h" -#include "ldap_int_thread.h" +#include "ldap_pvt_thread.h" #include #include @@ -141,7 +141,7 @@ lwp_create_stack( void *(*func)(), void *arg, int stackno ) } int -ldap_int_thread_create( ldap_int_thread_t * thread, +ldap_pvt_thread_create( ldap_pvt_thread_t * thread, int detach, void *(*start_routine)( void *), void *arg) @@ -157,13 +157,13 @@ ldap_int_thread_create( ldap_int_thread_t * thread, } void -ldap_int_thread_exit( void *retval ) +ldap_pvt_thread_exit( void *retval ) { lwp_destroy( SELF ); } unsigned int -ldap_int_thread_sleep( +ldap_pvt_thread_sleep( unsigned int interval ) { @@ -265,27 +265,27 @@ lwp_scheduler( } int -ldap_int_thread_join( ldap_int_thread_t thread, void **thread_return ) +ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return ) { lwp_join( thread ); return 0; } int -ldap_int_thread_kill( ldap_int_thread_t thread, int signo ) +ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo ) { return 0; } int -ldap_int_thread_yield( void ) +ldap_pvt_thread_yield( void ) { lwp_yield( SELF ); return 0; } int -ldap_int_thread_cond_init( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond ) { /* * lwp cv_create requires the monitor id be passed in @@ -301,14 +301,14 @@ ldap_int_thread_cond_init( ldap_int_thread_cond_t *cond ) } int -ldap_int_thread_cond_signal( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond ) { return( cond->lcv_created ? cv_notify( cv->lcv_cv ) : 0 ); } int -ldap_int_thread_cond_wait( ldap_int_thread_cond_t *cond, - ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, + ldap_int_thread_mutex_t *mutex ) { if ( ! cond->lcv_created ) { cv_create( &cond->lcv_cv, *mutex ); @@ -319,43 +319,43 @@ ldap_int_thread_cond_wait( ldap_int_thread_cond_t *cond, } int -ldap_int_thread_mutex_init( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex ) { return( mon_create( mutex ) ); } int -ldap_int_thread_mutex_destroy( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) { return( mon_destroy( *mutex ) ); } int -ldap_int_thread_mutex_lock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex ) { return( mon_enter( *mutex ) ); } int -ldap_int_thread_mutex_unlock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) { return( mon_exit( *mutex ) ); } int -ldap_int_thread_mutex_trylock( ldap_int_thread_mutex_t *mp ) +ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp ) { return( mon_cond_enter( *mp ) ); } int -ldap_int_thread_cond_destroy( ldap_pvt_thread_cond_t *cv ) +ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv ) { return( cv->lcv_created ? cv_destroy( cv->lcv_cv ) : 0 ); } int -ldap_int_thread_cond_broadcast( ldap_int_thread_cond_t *cv ) +ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cv ) { return( cv->lcv_created ? cv_broadcast( cv->lcv_cv ) : 0 ); } diff --git a/libraries/libldap_r/thr_nt.c b/libraries/libldap_r/thr_nt.c index 14cdecb59e..935bf4bd13 100644 --- a/libraries/libldap_r/thr_nt.c +++ b/libraries/libldap_r/thr_nt.c @@ -15,7 +15,7 @@ #if defined( HAVE_NT_THREADS ) -#include "ldap_int_thread.h" +#include "ldap_pvt_thread.h" int ldap_int_thread_initialize( void ) @@ -30,24 +30,24 @@ ldap_int_thread_destroy( void ) } int -ldap_int_thread_create( ldap_int_thread_t * thread, +ldap_pvt_thread_create( ldap_pvt_thread_t * thread, int detach, void *(*start_routine)( void *), void *arg) { - *thread = (ldap_int_thread_t)_beginthread( (void *) start_routine, + *thread = (ldap_pvt_thread_t)_beginthread( (void *) start_routine, 0, arg ); return ( (unsigned long)*thread == -1 ? -1 : 0 ); } void -ldap_int_thread_exit( void *retval ) +ldap_pvt_thread_exit( void *retval ) { _endthread( ); } int -ldap_int_thread_join( ldap_int_thread_t thread, void **thread_return ) +ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return ) { DWORD status; status = WaitForSingleObject( (HANDLE) thread, INFINITE ); @@ -58,42 +58,42 @@ ldap_int_thread_join( ldap_int_thread_t thread, void **thread_return ) } int -ldap_int_thread_kill( ldap_int_thread_t thread, int signo ) +ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo ) { return 0; } int -ldap_int_thread_yield( void ) +ldap_pvt_thread_yield( void ) { Sleep( 0 ); return 0; } int -ldap_int_thread_cond_init( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond ) { *cond = CreateEvent( NULL, FALSE, FALSE, NULL ); return( 0 ); } int -ldap_int_thread_cond_destroy( ldap_int_thread_cond_t *cv ) +ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv ) { CloseHandle( *cv ); return( 0 ); } int -ldap_int_thread_cond_signal( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond ) { SetEvent( *cond ); return( 0 ); } int -ldap_int_thread_cond_wait( ldap_int_thread_cond_t *cond, - ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, + ldap_pvt_thread_mutex_t *mutex ) { ReleaseMutex( *mutex ); SignalObjectAndWait( *mutex, *cond, INFINITE, FALSE ); @@ -102,42 +102,42 @@ ldap_int_thread_cond_wait( ldap_int_thread_cond_t *cond, } int -ldap_int_thread_cond_broadcast( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond ) { SetEvent( *cond ); return( 0 ); } int -ldap_int_thread_mutex_init( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex ) { *mutex = CreateMutex( NULL, 0, NULL ); return ( 0 ); } int -ldap_int_thread_mutex_destroy( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) { CloseHandle( *mutex ); return ( 0 ); } int -ldap_int_thread_mutex_lock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex ) { WaitForSingleObject( *mutex, INFINITE ); return ( 0 ); } int -ldap_int_thread_mutex_unlock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) { ReleaseMutex( *mutex ); return ( 0 ); } int -ldap_int_thread_mutex_trylock( ldap_int_thread_mutex_t *mp ) +ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp ) { DWORD status; diff --git a/libraries/libldap_r/thr_posix.c b/libraries/libldap_r/thr_posix.c index bb1fdb279f..95d30f1b4b 100644 --- a/libraries/libldap_r/thr_posix.c +++ b/libraries/libldap_r/thr_posix.c @@ -18,26 +18,23 @@ #include -#include "ldap_int_thread.h" +#include "ldap_pvt_thread.h" #if HAVE_PTHREADS_D4 -# define LDAP_PVT_THREAD_ATTR_DEFAULT pthread_attr_default -# define LDAP_PVT_THREAD_CONDATTR_DEFAULT pthread_condattr_default -# define LDAP_PVT_THREAD_MUTEXATTR_DEFAULT pthread_mutexattr_default +# define LDAP_INT_THREAD_ATTR_DEFAULT pthread_attr_default +# define LDAP_INT_THREAD_CONDATTR_DEFAULT pthread_condattr_default +# define LDAP_INT_THREAD_MUTEXATTR_DEFAULT pthread_mutexattr_default #else -# define LDAP_PVT_THREAD_ATTR_DEFAULT NULL -# define LDAP_PVT_THREAD_CONDATTR_DEFAULT NULL -# define LDAP_PVT_THREAD_MUTEXATTR_DEFAULT NULL +# define LDAP_INT_THREAD_ATTR_DEFAULT NULL +# define LDAP_INT_THREAD_CONDATTR_DEFAULT NULL +# define LDAP_INT_THREAD_MUTEXATTR_DEFAULT NULL #endif int ldap_int_thread_initialize( void ) { -#if defined( LDAP_THREAD_CONCURRENCY ) && HAVE_PTHREAD_SETCONCURRENCY - ldap_int_thread_set_concurrency( LDAP_THREAD_CONCURRENCY ); -#endif return 0; } @@ -49,7 +46,7 @@ ldap_int_thread_destroy( void ) #ifdef HAVE_PTHREAD_SETCONCURRENCY int -ldap_int_thread_set_concurrency(int n) +ldap_pvt_thread_set_concurrency(int n) { #ifdef HAVE_PTHREAD_SETCONCURRENCY return pthread_setconcurrency( n ); @@ -63,7 +60,7 @@ ldap_int_thread_set_concurrency(int n) #ifdef HAVE_PTHREAD_GETCONCURRENCY int -ldap_int_thread_get_concurrency(void) +ldap_pvt_thread_get_concurrency(void) { #ifdef HAVE_PTHREAD_GETCONCURRENCY return pthread_getconcurrency(); @@ -76,7 +73,7 @@ ldap_int_thread_get_concurrency(void) #endif int -ldap_int_thread_create( ldap_int_thread_t * thread, +ldap_pvt_thread_create( ldap_pvt_thread_t * thread, int detach, void *(*start_routine)( void * ), void *arg) @@ -91,7 +88,7 @@ ldap_int_thread_create( ldap_int_thread_t * thread, rtn = pthread_create( thread, &attr, start_routine, arg ); #else - rtn = pthread_create( thread, LDAP_PVT_THREAD_ATTR_DEFAULT, + rtn = pthread_create( thread, LDAP_INT_THREAD_ATTR_DEFAULT, start_routine, arg ); #endif @@ -106,13 +103,13 @@ ldap_int_thread_create( ldap_int_thread_t * thread, } void -ldap_int_thread_exit( void *retval ) +ldap_pvt_thread_exit( void *retval ) { pthread_exit( retval ); } int -ldap_int_thread_join( ldap_int_thread_t thread, void **thread_return ) +ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return ) { #if !defined( HAVE_PTHREADS_FINAL ) void *dummy; @@ -123,7 +120,7 @@ ldap_int_thread_join( ldap_int_thread_t thread, void **thread_return ) } int -ldap_int_thread_kill( ldap_int_thread_t thread, int signo ) +ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo ) { #ifdef HAVE_PTHREAD_KILL return pthread_kill( thread, signo ); @@ -136,7 +133,7 @@ ldap_int_thread_kill( ldap_int_thread_t thread, int signo ) } int -ldap_int_thread_yield( void ) +ldap_pvt_thread_yield( void ) { #ifdef _POSIX_THREAD_IS_GNU_PTH sched_yield(); @@ -158,62 +155,62 @@ ldap_int_thread_yield( void ) } int -ldap_int_thread_cond_init( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond ) { - return pthread_cond_init( cond, LDAP_PVT_THREAD_CONDATTR_DEFAULT ); + return pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT ); } int -ldap_int_thread_cond_destroy( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cond ) { return pthread_cond_destroy( cond ); } int -ldap_int_thread_cond_signal( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond ) { return pthread_cond_signal( cond ); } int -ldap_int_thread_cond_broadcast( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond ) { return pthread_cond_broadcast( cond ); } int -ldap_int_thread_cond_wait( ldap_int_thread_cond_t *cond, - ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, + ldap_pvt_thread_mutex_t *mutex ) { return pthread_cond_wait( cond, mutex ); } int -ldap_int_thread_mutex_init( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex ) { - return pthread_mutex_init( mutex, LDAP_PVT_THREAD_MUTEXATTR_DEFAULT ); + return pthread_mutex_init( mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT ); } int -ldap_int_thread_mutex_destroy( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) { return pthread_mutex_destroy( mutex ); } int -ldap_int_thread_mutex_lock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex ) { return pthread_mutex_lock( mutex ); } int -ldap_int_thread_mutex_trylock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex ) { return pthread_mutex_trylock( mutex ); } int -ldap_int_thread_mutex_unlock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) { return pthread_mutex_unlock( mutex ); } diff --git a/libraries/libldap_r/thr_pth.c b/libraries/libldap_r/thr_pth.c index d35e485f27..15fcac75a8 100644 --- a/libraries/libldap_r/thr_pth.c +++ b/libraries/libldap_r/thr_pth.c @@ -15,7 +15,7 @@ #if defined( HAVE_GNU_PTH ) -#include "ldap_int_thread.h" +#include "ldap_pvt_thread.h" /******************* * * @@ -28,9 +28,11 @@ static pth_attr_t detach_attr; int ldap_int_thread_initialize( void ) { + if( !pth_init() ) { + return -1; + } detach_attr = pth_attr_new(); - pth_attr_set( detach_attr, PTH_ATTR_JOINABLE, FALSE ); - return pth_init(); + return pth_attr_set( detach_attr, PTH_ATTR_JOINABLE, FALSE ); } int @@ -42,7 +44,7 @@ ldap_int_thread_destroy( void ) } int -ldap_int_thread_create( ldap_int_thread_t * thread, +ldap_pvt_thread_create( ldap_pvt_thread_t * thread, int detach, void *(*start_routine)( void *), void *arg) @@ -54,88 +56,88 @@ ldap_int_thread_create( ldap_int_thread_t * thread, } void -ldap_int_thread_exit( void *retval ) +ldap_pvt_thread_exit( void *retval ) { pth_exit( retval ); } -int ldap_int_thread_join( ldap_int_thread_t thread, void **thread_return ) +int ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return ) { pth_join( thread, thread_return ); return 0; } int -ldap_int_thread_kill( ldap_int_thread_t thread, int signo ) +ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo ) { pth_raise( thread, signo ); return 0; } int -ldap_int_thread_yield( void ) +ldap_pvt_thread_yield( void ) { pth_yield(NULL); return 0; } int -ldap_int_thread_cond_init( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond ) { return( pth_cond_init( cond ) ); } int -ldap_int_thread_cond_signal( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond ) { return( pth_cond_notify( cond, 0 ) ); } int -ldap_int_thread_cond_broadcast( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond ) { return( pth_cond_notify( cond, 1 ) ); } int -ldap_int_thread_cond_wait( ldap_int_thread_cond_t *cond, - ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, + ldap_pvt_thread_mutex_t *mutex ) { return( pth_cond_await( cond, mutex, NULL ) ); } int -ldap_int_thread_cond_destroy( ldap_int_thread_cond_t *cv ) +ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv ) { return 0; } int -ldap_int_thread_mutex_init( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex ) { return( pth_mutex_init( mutex ) ); } int -ldap_int_thread_mutex_destroy( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) { return 0; } int -ldap_int_thread_mutex_lock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex ) { return( pth_mutex_acquire( mutex, 0, NULL ) ); } int -ldap_int_thread_mutex_unlock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) { return( pth_mutex_release( mutex ) ); } int -ldap_int_thread_mutex_trylock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex ) { return( pth_mutex_acquire( mutex, 1, NULL ) ); } diff --git a/libraries/libldap_r/thr_sleep.c b/libraries/libldap_r/thr_sleep.c deleted file mode 100644 index fac90d0825..0000000000 --- a/libraries/libldap_r/thr_sleep.c +++ /dev/null @@ -1,57 +0,0 @@ -/* $OpenLDAP$ */ -/* - * Copyright (c) 1996 Regents of the University of Michigan. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and that due credit is given - * to the University of Michigan at Ann Arbor. The name of the University - * may not be used to endorse or promote products derived from this - * software without specific prior written permission. This software - * is provided ``as is'' without express or implied warranty. - */ - -/* - * ldap_pvt_thread_sleep.c - allow a thread to sleep without putting - * the whole process (e.g. pod under lwp) to sleep. - * - * Contains platform-specific code to allow this: - * - * Under non-preemptive threads packages like SunOS lwp, tsleep() adds - * the thread to a list of sleepers. The lwp_scheduler process takes - * care of resuming suspended threads. - * - * Under a fully-preemptive threads package, like Solaris threads, - * tsleep just calls sleep(), and there is no scheduler thread. Life - * is so much simpler... - */ - -#include "portable.h" - -#if !defined( HAVE_LWP ) - -#include -#include -#include /* get sleep() */ - -#include "ldap_pvt_thread.h" - - -/* - * Here we assume we have fully preemptive threads and that sleep() - * does the right thing. - */ -unsigned int -ldap_pvt_thread_sleep( - unsigned int interval -) -{ - sleep( interval ); - return 0; -} - -#else - -/* LWP implementation of sleep can be found in thr_lwp.c */ - -#endif /* HAVE_LWP */ diff --git a/libraries/libldap_r/thr_stub.c b/libraries/libldap_r/thr_stub.c index 6759117904..e473e0e557 100644 --- a/libraries/libldap_r/thr_stub.c +++ b/libraries/libldap_r/thr_stub.c @@ -15,7 +15,7 @@ #if defined( NO_THREADS ) -#include "ldap_int_thread.h" +#include "ldap_pvt_thread.h" /*********************************************************************** * * @@ -39,7 +39,7 @@ ldap_int_thread_destroy( void ) static void* ldap_int_status = NULL; int -ldap_int_thread_create( ldap_int_thread_t * thread, +ldap_pvt_thread_create( ldap_pvt_thread_t * thread, int detach, void *(*start_routine)(void *), void *arg) @@ -50,7 +50,7 @@ ldap_int_thread_create( ldap_int_thread_t * thread, } void -ldap_int_thread_exit( void *retval ) +ldap_pvt_thread_exit( void *retval ) { if( retval != NULL ) { ldap_int_status = retval; @@ -59,83 +59,119 @@ ldap_int_thread_exit( void *retval ) } int -ldap_int_thread_join( ldap_int_thread_t thread, void **status ) +ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **status ) { if(status != NULL) *status = ldap_int_status; return 0; } int -ldap_int_thread_kill( ldap_int_thread_t thread, int signo ) +ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo ) { return 0; } int -ldap_int_thread_yield( void ) +ldap_pvt_thread_yield( void ) { return 0; } int -ldap_int_thread_cond_init( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond ) { return 0; } int -ldap_int_thread_cond_destroy( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cond ) { return 0; } int -ldap_int_thread_cond_signal( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond ) { return 0; } int -ldap_int_thread_cond_broadcast( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond ) { return 0; } int -ldap_int_thread_cond_wait( ldap_int_thread_cond_t *cond, - ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, + ldap_pvt_thread_mutex_t *mutex ) { return 0; } int -ldap_int_thread_mutex_init( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex ) { return 0; } int -ldap_int_thread_mutex_destroy( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) { return 0; } int -ldap_int_thread_mutex_lock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex ) { return 0; } int -ldap_int_thread_mutex_trylock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex ) { return 0; } int -ldap_int_thread_mutex_unlock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) { return 0; } +/* + * NO_THREADS requires a separate tpool implementation since + * generic ldap_pvt_thread_pool_wrapper loops forever. + */ +int +ldap_pvt_thread_pool_init ( + ldap_pvt_thread_pool_t *pool_out, + int max_concurrency, int max_pending ) +{ + *pool_out = NULL; + return(0); +} + +int +ldap_pvt_thread_pool_submit ( + ldap_pvt_thread_pool_t *pool, + void *(*start_routine)( void * ), void *arg ) +{ + (start_routine)(arg); + return(0); +} + +int +ldap_pvt_thread_pool_backload ( + ldap_pvt_thread_pool_t *pool ) +{ + return(0); +} + +int +ldap_pvt_thread_pool_destroy ( + ldap_pvt_thread_pool_t *pool, int run_pending ) +{ + return(0); +} + #endif /* NO_THREADS */ diff --git a/libraries/libldap_r/thr_thr.c b/libraries/libldap_r/thr_thr.c index 949052a3fd..ee89e2e640 100644 --- a/libraries/libldap_r/thr_thr.c +++ b/libraries/libldap_r/thr_thr.c @@ -15,7 +15,7 @@ #if defined( HAVE_THR ) -#include "ldap_int_thread.h" +#include "ldap_pvt_thread.h" /******************* * * @@ -26,9 +26,6 @@ int ldap_int_thread_initialize( void ) { -#ifdef LDAP_THREAD_CONCURRENCY - thr_setconcurrency( LDAP_THREAD_CONCURRENCY ); -#endif return 0; } @@ -38,20 +35,24 @@ ldap_int_thread_destroy( void ) return 0; } +#ifdef LDAP_THREAD_HAVE_SETCONCURRENCY int -ldap_int_thread_set_concurrency(int n) +ldap_pvt_thread_set_concurrency(int n) { return thr_setconcurrency( n ); } +#endif +#ifdef LDAP_THREAD_HAVE_GETCONCURRENCY int -ldap_int_thread_get_concurrency(void) +ldap_pvt_thread_get_concurrency(void) { return thr_getconcurrency(); } +#endif int -ldap_int_thread_create( ldap_int_thread_t * thread, +ldap_pvt_thread_create( ldap_pvt_thread_t * thread, int detach, void *(*start_routine)( void *), void *arg) @@ -62,88 +63,88 @@ ldap_int_thread_create( ldap_int_thread_t * thread, } void -ldap_int_thread_exit( void *retval ) +ldap_pvt_thread_exit( void *retval ) { thr_exit( NULL ); } -int ldap_int_thread_join( ldap_int_thread_t thread, void **thread_return ) +int ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return ) { thr_join( thread, NULL, thread_return ); return 0; } int -ldap_int_thread_kill( ldap_int_thread_t thread, int signo ) +ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo ) { thr_kill( thread, signo ); return 0; } int -ldap_int_thread_yield( void ) +ldap_pvt_thread_yield( void ) { thr_yield(); return 0; } int -ldap_int_thread_cond_init( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond ) { return( cond_init( cond, USYNC_THREAD, NULL ) ); } int -ldap_int_thread_cond_signal( ldap_int_thread_cond_t *cond ) +ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond ) { return( cond_signal( cond ) ); } int -ldap_int_thread_cond_broadcast( ldap_int_thread_cond_t *cv ) +ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cv ) { return( cond_broadcast( cv ) ); } int -ldap_int_thread_cond_wait( ldap_int_thread_cond_t *cond, - ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, + ldap_pvt_thread_mutex_t *mutex ) { return( cond_wait( cond, mutex ) ); } int -ldap_int_thread_cond_destroy( ldap_int_thread_cond_t *cv ) +ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv ) { return( cond_destroy( cv ) ); } int -ldap_int_thread_mutex_init( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex ) { return( mutex_init( mutex, USYNC_THREAD, NULL ) ); } int -ldap_int_thread_mutex_destroy( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) { return( mutex_destroy( mutex ) ); } int -ldap_int_thread_mutex_lock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex ) { return( mutex_lock( mutex ) ); } int -ldap_int_thread_mutex_unlock( ldap_int_thread_mutex_t *mutex ) +ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) { return( mutex_unlock( mutex ) ); } int -ldap_int_thread_mutex_trylock( ldap_int_thread_mutex_t *mp ) +ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp ) { return( mutex_trylock( mp ) ); } diff --git a/libraries/libldap_r/threads.c b/libraries/libldap_r/threads.c index 22f3e4508a..9f845fe953 100644 --- a/libraries/libldap_r/threads.c +++ b/libraries/libldap_r/threads.c @@ -17,527 +17,71 @@ #include #include -#include "ldap_int_thread.h" #include "ldap_pvt_thread.h" -enum { - LDAP_PVT_THREAD_POOL_RUNNING, - LDAP_PVT_THREAD_POOL_FINISHING, - LDAP_PVT_THREAD_POOL_STOPPING -}; -typedef struct t_ldap_pvt_thread_listelement { - struct t_ldap_pvt_thread_listelement *next; -} ldap_pvt_thread_listelement, *ldap_pvt_thread_list; - -struct t_ldap_pvt_thread_pool { - struct t_ldap_pvt_thread_pool *ltp_next; - ldap_pvt_thread_mutex_t ltp_mutex; - ldap_pvt_thread_cond_t ltp_cond; - ldap_pvt_thread_list ltp_pending_list; - long ltp_state; - long ltp_max_count; - long ltp_max_pending; - long ltp_pending_count; - long ltp_active_count; - long ltp_open_count; -}; - -typedef struct t_ldap_pvt_thread_ctx { - struct t_ldap_pvt_thread_ctx *ltc_next; - void *(*ltc_start_routine)( void *); - void *ltc_arg; -} ldap_pvt_thread_ctx; - -#ifndef NO_THREADS -ldap_pvt_thread_list ldap_pvt_thread_pool_list = NULL; -ldap_pvt_thread_mutex_t ldap_pvt_thread_pool_mutex; -#endif - -int ldap_pvt_thread_pool_startup ( void ); -int ldap_pvt_thread_pool_shutdown ( void ); -void *ldap_pvt_thread_pool_wrapper( ldap_pvt_thread_pool_t pool ); -void *ldap_pvt_thread_enlist( ldap_pvt_thread_list *list, void *elem ); -void *ldap_pvt_thread_delist( ldap_pvt_thread_list *list, void *elem ); -void *ldap_pvt_thread_onlist( ldap_pvt_thread_list *list, void *elem ); +/* + * Common LDAP thread routines + * see thr_*.c for implementation specific routines + * see rdwr.c for generic reader/writer lock implementation + * see tpool.c for generic thread pool implementation + */ -int -ldap_pvt_thread_initialize ( void ) +int ldap_pvt_thread_initialize( void ) { int rc; + static int init = 0; + + /* we only get one shot at this */ + if( init++ ) return -1; rc = ldap_int_thread_initialize(); - if (rc == 0) { - ldap_pvt_thread_pool_startup(); - } - return rc; + if( rc ) return rc; + +#ifndef LDAP_THREAD_HAVE_TPOOL + rc = ldap_int_thread_pool_startup(); + if( rc ) return rc; +#endif + + return 0; } -int -ldap_pvt_thread_destroy ( void ) +int ldap_pvt_thread_destroy( void ) { - ldap_pvt_thread_pool_shutdown(); - return ldap_int_thread_destroy(); +#ifndef LDAP_THREAD_HAVE_TPOOL + (void) ldap_int_thread_pool_shutdown(); +#endif + (void) ldap_int_thread_destroy(); } +#ifndef LDAP_THREAD_HAVE_GETCONCURRENCY int ldap_pvt_thread_get_concurrency ( void ) { -#ifdef HAVE_GETCONCURRENCY - return ldap_int_thread_get_concurrency(); -#else return 1; -#endif } +#endif +#ifndef LDAP_THREAD_HAVE_SETCONCURRENCY int ldap_pvt_thread_set_concurrency ( int concurrency ) { -#ifdef HAVE_SETCONCURRENCY - return ldap_int_thread_set_concurrency(concurrency); -#else return 1; -#endif -} - -int -ldap_pvt_thread_create ( - ldap_pvt_thread_t * thread, - int detach, - void *(*start_routine)( void * ), - void *arg) -{ - return ldap_int_thread_create(thread, detach, start_routine, arg); -} - -void -ldap_pvt_thread_exit ( void *retval ) -{ - ldap_int_thread_exit(retval); } +#endif -int -ldap_pvt_thread_join ( ldap_pvt_thread_t thread, void **status ) -{ - return ldap_int_thread_join(thread, status); -} - -int -ldap_pvt_thread_kill ( ldap_pvt_thread_t thread, int signo ) -{ - return ldap_int_thread_kill(thread, signo); -} - -int -ldap_pvt_thread_yield ( void ) -{ - return ldap_int_thread_yield(); -} - -int -ldap_pvt_thread_cond_init ( ldap_pvt_thread_cond_t *cond ) -{ - return ldap_int_thread_cond_init(cond); -} - -int -ldap_pvt_thread_cond_destroy ( ldap_pvt_thread_cond_t *cond ) -{ - return ldap_int_thread_cond_destroy(cond); -} - -int -ldap_pvt_thread_cond_signal ( ldap_pvt_thread_cond_t *cond ) -{ - return ldap_int_thread_cond_signal(cond); -} - -int -ldap_pvt_thread_cond_broadcast ( ldap_pvt_thread_cond_t *cond ) -{ - return ldap_int_thread_cond_broadcast(cond); -} - -int -ldap_pvt_thread_cond_wait ( - ldap_pvt_thread_cond_t *cond, - ldap_pvt_thread_mutex_t *mutex ) -{ - return ldap_int_thread_cond_wait(cond, mutex); -} - -int -ldap_pvt_thread_mutex_init ( ldap_pvt_thread_mutex_t *mutex ) -{ - return ldap_int_thread_mutex_init(mutex); -} - -int -ldap_pvt_thread_mutex_destroy ( ldap_pvt_thread_mutex_t *mutex ) -{ - return ldap_int_thread_mutex_destroy(mutex); -} - -int -ldap_pvt_thread_mutex_lock ( ldap_pvt_thread_mutex_t *mutex ) -{ - return ldap_int_thread_mutex_lock(mutex); -} - -int -ldap_pvt_thread_mutex_trylock ( ldap_pvt_thread_mutex_t *mutex ) -{ - return ldap_int_thread_mutex_trylock(mutex); -} - -int -ldap_pvt_thread_mutex_unlock ( ldap_pvt_thread_mutex_t *mutex ) -{ - return ldap_int_thread_mutex_unlock(mutex); -} - -#ifdef NO_THREADS - -/* There must be a separate implementation when NO_THREADS is on. - * Since ldap_pvt_thread_pool_wrapper loops, there's no way to - * simply let the underlying (stub) thread implementation take - * care of things (unless there was an #ifdef that removed the - * "while" in ldap_pvt_thread_pool_wrapper, but why do all the - * extra work of init/submit/destroy when all that's needed - * are these stubs?) +#ifndef LDAP_THREAD_HAVE_SLEEP +/* + * Here we assume we have fully preemptive threads and that sleep() + * does the right thing. */ -int -ldap_pvt_thread_pool_startup ( void ) -{ - return(0); -} - -int -ldap_pvt_thread_pool_shutdown ( void ) -{ - return(0); -} - -int -ldap_pvt_thread_pool_initialize ( ldap_pvt_thread_pool_t *pool_out, int max_concurrency, int max_pending ) -{ - *pool_out = NULL; - return(0); -} - -int -ldap_pvt_thread_pool_submit ( ldap_pvt_thread_pool_t pool, void *(*start_routine)( void * ), void *arg ) -{ - (start_routine)(arg); - return(0); -} - -int -ldap_pvt_thread_pool_backload ( ldap_pvt_thread_pool_t pool ) +unsigned int +ldap_pvt_thread_sleep( + unsigned int interval +) { - return(0); + sleep( interval ); + return 0; } - -int -ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t pool, int run_pending ) -{ - return(0); -} - -#else - -int -ldap_pvt_thread_pool_startup ( void ) -{ - return ldap_pvt_thread_mutex_init(&ldap_pvt_thread_pool_mutex); -} - -int -ldap_pvt_thread_pool_shutdown ( void ) -{ - while (ldap_pvt_thread_pool_list != NULL) { - ldap_pvt_thread_pool_destroy((ldap_pvt_thread_pool_t)ldap_pvt_thread_pool_list, 0); - } - ldap_pvt_thread_mutex_destroy(&ldap_pvt_thread_pool_mutex); - return(0); -} - -int -ldap_pvt_thread_pool_initialize ( ldap_pvt_thread_pool_t *pool_out, int max_concurrency, int max_pending ) -{ - ldap_pvt_thread_pool_t pool; - ldap_pvt_thread_t thr; - - *pool_out = NULL; - pool = (ldap_pvt_thread_pool_t)calloc(1, sizeof(struct t_ldap_pvt_thread_pool)); - if (pool == NULL) - return(-1); - - ldap_pvt_thread_mutex_init(&pool->ltp_mutex); - ldap_pvt_thread_cond_init(&pool->ltp_cond); - pool->ltp_state = LDAP_PVT_THREAD_POOL_RUNNING; - pool->ltp_max_count = max_concurrency; - pool->ltp_max_pending = max_pending; - ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex); - ldap_pvt_thread_enlist(&ldap_pvt_thread_pool_list, pool); - ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex); - - /* start up one thread, just so there is one */ - pool->ltp_open_count++; - if (ldap_pvt_thread_create( &thr, 1, (void *)ldap_pvt_thread_pool_wrapper, pool ) != 0) { - /* couldn't start one? then don't start any */ - ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex); - ldap_pvt_thread_delist(&ldap_pvt_thread_pool_list, pool); - ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex); - ldap_pvt_thread_cond_destroy(&pool->ltp_cond); - ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex); - free(pool); - return(-1); - } - - *pool_out = pool; - return(0); -} - -int -ldap_pvt_thread_pool_submit ( ldap_pvt_thread_pool_t pool, void *(*start_routine)( void * ), void *arg ) -{ - ldap_pvt_thread_ctx *ctx; - int need_thread = 0; - ldap_pvt_thread_t thr; - - if (pool == NULL) - return(-1); - - ctx = (ldap_pvt_thread_ctx *)calloc(1, sizeof(ldap_pvt_thread_ctx)); - if (ctx == NULL) - return(-1); - - ctx->ltc_start_routine = start_routine; - ctx->ltc_arg = arg; - - ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); - if (pool->ltp_state != LDAP_PVT_THREAD_POOL_RUNNING - || (pool->ltp_max_pending > 0 && pool->ltp_pending_count >= pool->ltp_max_pending)) - { - ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); - free(ctx); - return(-1); - } - pool->ltp_pending_count++; - ldap_pvt_thread_enlist(&pool->ltp_pending_list, ctx); - ldap_pvt_thread_cond_signal(&pool->ltp_cond); - if ((pool->ltp_open_count <= 0 - || pool->ltp_pending_count > 1 - || pool->ltp_open_count == pool->ltp_active_count) - && (pool->ltp_max_count <= 0 - || pool->ltp_open_count < pool->ltp_max_count)) - { - pool->ltp_open_count++; - need_thread = 1; - } - ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); - - if (need_thread) { - if (ldap_pvt_thread_create( &thr, 1, (void *)ldap_pvt_thread_pool_wrapper, pool ) != 0) { - /* couldn't create thread. back out of - * ltp_open_count and check for even worse things. - */ - ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); - pool->ltp_open_count--; - if (pool->ltp_open_count == 0) { - /* no open threads at all?!? this will never happen - * because we always leave at least one thread open. - */ - if (ldap_pvt_thread_delist(&pool->ltp_pending_list, ctx)) { - /* no open threads, context not handled, so - * back out of ltp_pending_count, free the context, - * report the error. - */ - pool->ltp_pending_count++; - ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); - free(ctx); - return(-1); - } - } - ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); - /* there is another open thread, so this - * context will be handled eventually. - * continue on and signal that the context - * is waiting. - */ - } - } - - return(0); -} - -int -ldap_pvt_thread_pool_backload ( ldap_pvt_thread_pool_t pool ) -{ - int count; - - if (pool == NULL) - return(0); - - ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); - count = pool->ltp_pending_count + pool->ltp_active_count; - ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); - return(count); -} - -int -ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t pool, int run_pending ) -{ - long waiting; - ldap_pvt_thread_ctx *ctx; - - if (pool == NULL) - return(-1); - - ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex); - pool = ldap_pvt_thread_delist(&ldap_pvt_thread_pool_list, pool); - ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex); - - if (pool == NULL) - return(-1); - - ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); - if (run_pending) - pool->ltp_state = LDAP_PVT_THREAD_POOL_FINISHING; - else - pool->ltp_state = LDAP_PVT_THREAD_POOL_STOPPING; - waiting = pool->ltp_open_count; - ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); - - /* broadcast could be used here, but only after - * it is fixed in the NT thread implementation - */ - while (--waiting >= 0) - ldap_pvt_thread_cond_signal(&pool->ltp_cond); - do { - ldap_pvt_thread_yield(); - ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); - waiting = pool->ltp_open_count; - ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); - } while (waiting > 0); - - while (ctx = (ldap_pvt_thread_ctx *)ldap_pvt_thread_delist(&pool->ltp_pending_list, NULL)) - free(ctx); - - ldap_pvt_thread_cond_destroy(&pool->ltp_cond); - ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex); - free(pool); - return(0); -} - -void * -ldap_pvt_thread_pool_wrapper ( ldap_pvt_thread_pool_t pool ) -{ - ldap_pvt_thread_ctx *ctx; - - ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); - - while (pool->ltp_state != LDAP_PVT_THREAD_POOL_STOPPING) { - - ctx = ldap_pvt_thread_delist(&pool->ltp_pending_list, NULL); - if (ctx == NULL) { - if (pool->ltp_state == LDAP_PVT_THREAD_POOL_FINISHING) - break; - /* we could check an idle timer here, and let the - * thread die if it has been inactive for a while. - * only die if there are other open threads (i.e., - * always have at least one thread open). - */ - - if (pool->ltp_state == LDAP_PVT_THREAD_POOL_RUNNING) - ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex); - - continue; - } - - pool->ltp_pending_count--; - pool->ltp_active_count++; - ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); - - (ctx->ltc_start_routine)(ctx->ltc_arg); - free(ctx); - ldap_pvt_thread_yield(); - - /* if we use an idle timer, here's - * a good place to update it - */ - - ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); - pool->ltp_active_count--; - } - - pool->ltp_open_count--; - ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); - - ldap_pvt_thread_exit(NULL); - return(NULL); -} - -void * -ldap_pvt_thread_enlist( ldap_pvt_thread_list *list, void *elem ) -{ - ldap_pvt_thread_listelement *prev; - - if (elem == NULL) - return(NULL); - - ((ldap_pvt_thread_listelement *)elem)->next = NULL; - if (*list == NULL) { - *list = elem; - return(elem); - } - - for (prev = *list ; prev->next != NULL; prev = prev->next) ; - prev->next = elem; - return(elem); -} - -void * -ldap_pvt_thread_delist( ldap_pvt_thread_list *list, void *elem ) -{ - ldap_pvt_thread_listelement *prev; - - if (*list == NULL) - return(NULL); - - if (elem == NULL) - elem = *list; - - if (*list == elem) { - *list = ((ldap_pvt_thread_listelement *)elem)->next; - return(elem); - } - - for (prev = *list ; prev->next != NULL; prev = prev->next) { - if (prev->next == elem) { - prev->next = ((ldap_pvt_thread_listelement *)elem)->next; - return(elem); - } - } - return(NULL); -} - -void * -ldap_pvt_thread_onlist( ldap_pvt_thread_list *list, void *elem ) -{ - ldap_pvt_thread_listelement *prev; - - if (elem == NULL || *list == NULL) - return(NULL); - - for (prev = *list ; prev != NULL; prev = prev->next) { - if (prev == elem) - return(elem); - } - - return(NULL); -} - -#endif /* NO_THREADS */ +#endif diff --git a/libraries/libldap_r/tpool.c b/libraries/libldap_r/tpool.c new file mode 100644 index 0000000000..af0c4f739d --- /dev/null +++ b/libraries/libldap_r/tpool.c @@ -0,0 +1,396 @@ +/* $OpenLDAP$ */ +/* + * Copyright 1998-2000 The OpenLDAP Foundation, Redwood City, California, USA + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted only + * as authorized by the OpenLDAP Public License. A copy of this + * license is available at http://www.OpenLDAP.org/license.html or + * in file LICENSE in the top-level directory of the distribution. + */ + +#include "portable.h" + +#include +#include + +#include +#include +#include + +#include "ldap-int.h" +#include "ldap_pvt_thread.h" + +#ifndef LDAP_THREAD_HAVE_TPOOL + +enum ldap_int_thread_pool_state { + LDAP_INT_THREAD_POOL_RUNNING, + LDAP_INT_THREAD_POOL_FINISHING, + LDAP_INT_THREAD_POOL_STOPPING +}; + +typedef struct ldap_int_thread_list_element_s { + struct ldap_int_thread_list_element_s *next; +} ldap_int_thread_list_element_t, *ldap_int_thread_list_t; + +struct ldap_int_thread_pool_s { + struct ldap_int_thread_pool_s *ltp_next; + ldap_pvt_thread_mutex_t ltp_mutex; + ldap_pvt_thread_cond_t ltp_cond; + ldap_int_thread_list_t ltp_pending_list; + long ltp_state; + long ltp_max_count; + long ltp_max_pending; + long ltp_pending_count; + long ltp_active_count; + long ltp_open_count; +}; + +typedef struct ldap_int_thread_ctx_s { + struct ldap_int_thread_ctx_s *ltc_next; + void *(*ltc_start_routine)( void *); + void *ltc_arg; +} ldap_int_thread_ctx_t; + +static ldap_int_thread_list_t ldap_int_thread_pool_list = NULL; +static ldap_pvt_thread_mutex_t ldap_pvt_thread_pool_mutex; + +static void *ldap_int_thread_pool_wrapper( + struct ldap_int_thread_pool_s *pool ); + +static void *ldap_int_thread_enlist( ldap_int_thread_list_t *list, void *elem ); +static void *ldap_int_thread_delist( ldap_int_thread_list_t *list, void *elem ); +static void *ldap_int_thread_onlist( ldap_int_thread_list_t *list, void *elem ); + +int +ldap_int_thread_pool_startup ( void ) +{ + return ldap_pvt_thread_mutex_init(&ldap_pvt_thread_pool_mutex); +} + +int +ldap_int_thread_pool_shutdown ( void ) +{ + while (ldap_int_thread_pool_list != NULL) { + struct ldap_int_thread_pool_s *pool = + (struct ldap_int_thread_pool_s *) ldap_int_thread_pool_list; + + ldap_pvt_thread_pool_destroy( &pool, 0); + } + ldap_pvt_thread_mutex_destroy(&ldap_pvt_thread_pool_mutex); + return(0); +} + +int +ldap_pvt_thread_pool_init ( + ldap_pvt_thread_pool_t *tpool, + int max_concurrency, + int max_pending ) +{ + int rc; + ldap_pvt_thread_pool_t pool; + ldap_pvt_thread_t thr; + + *tpool = NULL; + pool = (ldap_pvt_thread_pool_t) LDAP_CALLOC(1, + sizeof(struct ldap_int_thread_pool_s)); + + if (pool == NULL) return(-1); + + ldap_pvt_thread_mutex_init(&pool->ltp_mutex); + ldap_pvt_thread_cond_init(&pool->ltp_cond); + pool->ltp_state = LDAP_INT_THREAD_POOL_RUNNING; + pool->ltp_max_count = max_concurrency; + pool->ltp_max_pending = max_pending; + ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex); + ldap_int_thread_enlist(&ldap_int_thread_pool_list, pool); + ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex); + + /* start up one thread, just so there is one */ + pool->ltp_open_count++; + + rc = ldap_pvt_thread_create( &thr, 1, + (void *) ldap_int_thread_pool_wrapper, pool ); + + if( rc != 0) { + /* couldn't start one? then don't start any */ + ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex); + ldap_int_thread_delist(&ldap_int_thread_pool_list, pool); + ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex); + ldap_pvt_thread_cond_destroy(&pool->ltp_cond); + ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex); + free(pool); + return(-1); + } + + *tpool = pool; + return(0); +} + +int +ldap_pvt_thread_pool_submit ( + ldap_pvt_thread_pool_t *tpool, + void *(*start_routine)( void * ), void *arg ) +{ + struct ldap_int_thread_pool_s *pool; + ldap_int_thread_ctx_t *ctx; + int need_thread = 0; + ldap_pvt_thread_t thr; + + if (tpool == NULL) + return(-1); + + pool = *tpool; + + if (pool == NULL) + return(-1); + + ctx = (ldap_int_thread_ctx_t *) LDAP_CALLOC(1, + sizeof(ldap_int_thread_ctx_t)); + + if (ctx == NULL) return(-1); + + ctx->ltc_start_routine = start_routine; + ctx->ltc_arg = arg; + + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + if (pool->ltp_state != LDAP_INT_THREAD_POOL_RUNNING + || (pool->ltp_max_pending > 0 + && pool->ltp_pending_count >= pool->ltp_max_pending)) + { + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + free(ctx); + return(-1); + } + pool->ltp_pending_count++; + ldap_int_thread_enlist(&pool->ltp_pending_list, ctx); + ldap_pvt_thread_cond_signal(&pool->ltp_cond); + if ((pool->ltp_open_count <= 0 + || pool->ltp_pending_count > 1 + || pool->ltp_open_count == pool->ltp_active_count) + && (pool->ltp_max_count <= 0 + || pool->ltp_open_count < pool->ltp_max_count)) + { + pool->ltp_open_count++; + need_thread = 1; + } + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + + if (need_thread) { + int rc = ldap_pvt_thread_create( &thr, 1, + (void *)ldap_int_thread_pool_wrapper, pool ); + if (rc != 0) { + /* couldn't create thread. back out of + * ltp_open_count and check for even worse things. + */ + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + pool->ltp_open_count--; + if (pool->ltp_open_count == 0) { + /* no open threads at all?!? this will never happen + * because we always leave at least one thread open. + */ + if (ldap_int_thread_delist(&pool->ltp_pending_list, ctx)) { + /* no open threads, context not handled, so + * back out of ltp_pending_count, free the context, + * report the error. + */ + pool->ltp_pending_count++; + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + free(ctx); + return(-1); + } + } + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + /* there is another open thread, so this + * context will be handled eventually. + * continue on and signal that the context + * is waiting. + */ + } + } + + return(0); +} + +int +ldap_pvt_thread_pool_backload ( ldap_pvt_thread_pool_t *tpool ) +{ + struct ldap_int_thread_pool_s *pool; + int count; + + if (tpool == NULL) + return(-1); + + pool = *tpool; + + if (pool == NULL) + return(0); + + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + count = pool->ltp_pending_count + pool->ltp_active_count; + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + return(count); +} + +int +ldap_pvt_thread_pool_destroy ( ldap_pvt_thread_pool_t *tpool, int run_pending ) +{ + struct ldap_int_thread_pool_s *pool; + long waiting; + ldap_int_thread_ctx_t *ctx; + + if (tpool == NULL) + return(-1); + + pool = *tpool; + + if (pool == NULL) return(-1); + + ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex); + pool = ldap_int_thread_delist(&ldap_int_thread_pool_list, pool); + ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex); + + if (pool == NULL) return(-1); + + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + pool->ltp_state = run_pending + ? LDAP_INT_THREAD_POOL_FINISHING + : LDAP_INT_THREAD_POOL_STOPPING; + waiting = pool->ltp_open_count; + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + + /* broadcast could be used here, but only after + * it is fixed in the NT thread implementation + */ + while (--waiting >= 0) { + ldap_pvt_thread_cond_signal(&pool->ltp_cond); + } + + do { + ldap_pvt_thread_yield(); + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + waiting = pool->ltp_open_count; + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + } while (waiting > 0); + + while (ctx = (ldap_int_thread_ctx_t *)ldap_int_thread_delist( + &pool->ltp_pending_list, NULL)) + { + free(ctx); + } + + ldap_pvt_thread_cond_destroy(&pool->ltp_cond); + ldap_pvt_thread_mutex_destroy(&pool->ltp_mutex); + free(pool); + return(0); +} + +static void * +ldap_int_thread_pool_wrapper ( + struct ldap_int_thread_pool_s *pool ) +{ + ldap_int_thread_ctx_t *ctx; + + if (pool == NULL) + return NULL; + + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + + while (pool->ltp_state != LDAP_INT_THREAD_POOL_STOPPING) { + + ctx = ldap_int_thread_delist(&pool->ltp_pending_list, NULL); + if (ctx == NULL) { + if (pool->ltp_state == LDAP_INT_THREAD_POOL_FINISHING) + break; + /* we could check an idle timer here, and let the + * thread die if it has been inactive for a while. + * only die if there are other open threads (i.e., + * always have at least one thread open). + */ + + if (pool->ltp_state == LDAP_INT_THREAD_POOL_RUNNING) + ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex); + + continue; + } + + pool->ltp_pending_count--; + pool->ltp_active_count++; + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + + (ctx->ltc_start_routine)(ctx->ltc_arg); + free(ctx); + ldap_pvt_thread_yield(); + + /* if we use an idle timer, here's + * a good place to update it + */ + + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + pool->ltp_active_count--; + } + + pool->ltp_open_count--; + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + + ldap_pvt_thread_exit(NULL); + return(NULL); +} + +static void * +ldap_int_thread_enlist( ldap_int_thread_list_t *list, void *elem ) +{ + ldap_int_thread_list_element_t *prev; + + if (elem == NULL) return(NULL); + + ((ldap_int_thread_list_element_t *)elem)->next = NULL; + if (*list == NULL) { + *list = elem; + return(elem); + } + + for (prev = *list ; prev->next != NULL; prev = prev->next) ; + prev->next = elem; + return(elem); +} + +static void * +ldap_int_thread_delist( ldap_int_thread_list_t *list, void *elem ) +{ + ldap_int_thread_list_element_t *prev; + + if (*list == NULL) return(NULL); + + if (elem == NULL) elem = *list; + + if (*list == elem) { + *list = ((ldap_int_thread_list_element_t *)elem)->next; + return(elem); + } + + for (prev = *list ; prev->next != NULL; prev = prev->next) { + if (prev->next == elem) { + prev->next = ((ldap_int_thread_list_element_t *)elem)->next; + return(elem); + } + } + return(NULL); +} + +static void * +ldap_int_thread_onlist( ldap_int_thread_list_t *list, void *elem ) +{ + ldap_int_thread_list_element_t *prev; + + if (elem == NULL || *list == NULL) return(NULL); + + for (prev = *list ; prev != NULL; prev = prev->next) { + if (prev == elem) + return(elem); + } + + return(NULL); +} + +#endif /* LDAP_HAVE_THREAD_POOL */ diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index 36fa302a93..8315746be1 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -454,20 +454,6 @@ select_backend( const char * dn ) } } -#ifdef LDAP_ALLOW_NULL_SEARCH_BASE - /* Add greg@greg.rim.or.jp - * It's quick hack for cheap client - * Some browser offer a NULL base at ldap_search - * - * Should only be used as a last resort. -Kdz - */ - if(dnlen == 0) { - Debug( LDAP_DEBUG_TRACE, - "select_backend: use default backend\n", 0, 0, 0 ); - return( &backends[0] ); - } -#endif /* LDAP_ALLOW_NULL_SEARCH_BASE */ - return( NULL ); } diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 3a6312950d..9f78b99911 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -143,6 +143,27 @@ read_config( const char *fname ) return( 1 ); } + /* set thread concurrency */ + } else if ( strcasecmp( cargv[0], "concurrency" ) == 0 ) { + int c; + if ( cargc < 2 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing level in \"concurrency \" line\n", + fname, lineno, 0 ); + return( 1 ); + } + + c = atoi( cargv[1] ); + + if( c < 1 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: invalid level (%d) in \"concurrency \" line\n", + fname, lineno, c ); + return( 1 ); + } + + ldap_pvt_thread_set_concurrency( c ); + /* get pid file name */ } else if ( strcasecmp( cargv[0], "pidfile" ) == 0 ) { if ( cargc < 2 ) { diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 67d6cd0427..f1e075eb45 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -1128,7 +1128,8 @@ static int connection_op_activate( Connection *conn, Operation *op ) free( tmpdn ); } - status = ldap_pvt_thread_pool_submit( connection_pool, connection_operation, (void *) arg ); + status = ldap_pvt_thread_pool_submit( &connection_pool, + connection_operation, (void *) arg ); if ( status != 0 ) { Debug( LDAP_DEBUG_ANY, diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 4d53840022..61a7989be5 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -751,7 +751,7 @@ slapd_daemon_task( ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); - at = ldap_pvt_thread_pool_backload(connection_pool); + at = ldap_pvt_thread_pool_backload(&connection_pool); #if defined( HAVE_YIELDING_SELECT ) || defined( NO_THREADS ) tvp = NULL; @@ -1158,9 +1158,9 @@ slapd_daemon_task( Debug( LDAP_DEBUG_ANY, "slapd shutdown: waiting for %d threads to terminate\n", - ldap_pvt_thread_pool_backload(connection_pool), 0, 0 ); + ldap_pvt_thread_pool_backload(&connection_pool), 0, 0 ); - ldap_pvt_thread_pool_destroy(connection_pool, 1); + ldap_pvt_thread_pool_destroy(&connection_pool, 1); return NULL; } diff --git a/servers/slapd/init.c b/servers/slapd/init.c index 0039bdbfde..cda4397d1a 100644 --- a/servers/slapd/init.c +++ b/servers/slapd/init.c @@ -39,7 +39,6 @@ char **g_argv; * global variables that need mutex protection */ ldap_pvt_thread_pool_t connection_pool; - ldap_pvt_thread_mutex_t gmtime_mutex; #ifdef SLAPD_CRYPT ldap_pvt_thread_mutex_t crypt_mutex; @@ -94,7 +93,8 @@ slap_init( int mode, const char *name ) slap_name = name; (void) ldap_pvt_thread_initialize(); - ldap_pvt_thread_pool_initialize(&connection_pool, 0, 0); + + ldap_pvt_thread_pool_init(&connection_pool, 0, 0); ldap_pvt_thread_mutex_init( ¤ttime_mutex ); ldap_pvt_thread_mutex_init( &entry2str_mutex ); diff --git a/servers/slapd/monitor.c b/servers/slapd/monitor.c index 63c791dd58..ce1cd803da 100644 --- a/servers/slapd/monitor.c +++ b/servers/slapd/monitor.c @@ -90,7 +90,8 @@ monitor_info( } attr_merge( e, "version", vals ); - sprintf( buf, "%d", ldap_pvt_thread_pool_backload(connection_pool) ); + sprintf( buf, "%d", + ldap_pvt_thread_pool_backload( &connection_pool) ); val.bv_val = buf; val.bv_len = strlen( buf ); attr_merge( e, "threads", vals ); -- 2.39.5