diff --git a/include/ldap_pvt_thread.h b/include/ldap_pvt_thread.h index 5b65406731..da0a3fcdf0 100644 --- a/include/ldap_pvt_thread.h +++ b/include/ldap_pvt_thread.h @@ -138,7 +138,7 @@ typedef ldap_int_thread_pool_t ldap_pvt_thread_pool_t; LDAP_F( int ) ldap_pvt_thread_pool_init LDAP_P(( ldap_pvt_thread_pool_t *pool_out, - int max_concurrency, + int max_threads, int max_pending )); LDAP_F( int ) @@ -147,6 +147,11 @@ ldap_pvt_thread_pool_submit LDAP_P(( void *(*start_routine)( void * ), void *arg )); +LDAP_F( int ) +ldap_pvt_thread_pool_maxthreads LDAP_P(( + ldap_pvt_thread_pool_t *pool, + int max_threads )); + LDAP_F( int ) ldap_pvt_thread_pool_backload LDAP_P(( ldap_pvt_thread_pool_t *pool )); diff --git a/libraries/libldap_r/tpool.c b/libraries/libldap_r/tpool.c index ba44fb22cc..c99450c320 100644 --- a/libraries/libldap_r/tpool.c +++ b/libraries/libldap_r/tpool.c @@ -85,7 +85,7 @@ ldap_int_thread_pool_shutdown ( void ) int ldap_pvt_thread_pool_init ( ldap_pvt_thread_pool_t *tpool, - int max_concurrency, + int max_threads, int max_pending ) { ldap_pvt_thread_pool_t pool; @@ -104,7 +104,7 @@ ldap_pvt_thread_pool_init ( if (rc != 0) return(rc); pool->ltp_state = LDAP_INT_THREAD_POOL_RUNNING; - pool->ltp_max_count = max_concurrency; + pool->ltp_max_count = max_threads; 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); @@ -235,6 +235,25 @@ ldap_pvt_thread_pool_submit ( return(0); } +int +ldap_pvt_thread_pool_maxthreads ( ldap_pvt_thread_pool_t *tpool, int max_threads ) +{ + struct ldap_int_thread_pool_s *pool; + + if (tpool == NULL) + return(-1); + + pool = *tpool; + + if (pool == NULL) + return(-1); + + ldap_pvt_thread_mutex_lock(&pool->ltp_mutex); + pool->ltp_max_count = max_threads; + ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex); + return(0); +} + int ldap_pvt_thread_pool_backload ( ldap_pvt_thread_pool_t *tpool ) { @@ -325,6 +344,17 @@ ldap_int_thread_pool_wrapper ( if (ctx == NULL) { if (pool->ltp_state == LDAP_INT_THREAD_POOL_FINISHING) break; + if (pool->ltp_max_count > 0 + && pool->ltp_open_count > pool->ltp_max_count) + { + /* too many threads running (can happen if the + * maximum threads value is set during ongoing + * operation using ldap_pvt_thread_pool_maxthreads) + * so let this thread die. + */ + 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., diff --git a/servers/slapd/config.c b/servers/slapd/config.c index f5041fe007..e031402ec8 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -161,6 +161,27 @@ read_config( const char *fname ) ldap_pvt_thread_set_concurrency( c ); + /* set maximum threads in thread pool */ + } else if ( strcasecmp( cargv[0], "threads" ) == 0 ) { + int c; + if ( cargc < 2 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing count in \"threads \" line\n", + fname, lineno, 0 ); + return( 1 ); + } + + c = atoi( cargv[1] ); + + if( c < 0 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: invalid level (%d) in \"threads \" line\n", + fname, lineno, c ); + return( 1 ); + } + + ldap_pvt_thread_pool_maxthreads( &connection_pool, c ); + /* get pid file name */ } else if ( strcasecmp( cargv[0], "pidfile" ) == 0 ) { if ( cargc < 2 ) { diff --git a/servers/slapd/init.c b/servers/slapd/init.c index cda4397d1a..2e25add973 100644 --- a/servers/slapd/init.c +++ b/servers/slapd/init.c @@ -94,7 +94,7 @@ slap_init( int mode, const char *name ) (void) ldap_pvt_thread_initialize(); - ldap_pvt_thread_pool_init(&connection_pool, 0, 0); + ldap_pvt_thread_pool_init(&connection_pool, SLAP_MAX_WORKER_THREADS, 0); ldap_pvt_thread_mutex_init( ¤ttime_mutex ); ldap_pvt_thread_mutex_init( &entry2str_mutex ); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index e2ddbacca3..c55f231966 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -62,6 +62,8 @@ LDAP_BEGIN_DECL #define MAXREMATCHES 10 +#define SLAP_MAX_WORKER_THREADS 32 + /* psuedo error code indicating abandoned operation */ #define SLAPD_ABANDON (-1)