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.
This commit is contained in:
Kurt Zeilenga 2000-06-13 02:42:13 +00:00
parent 1bfcb4b039
commit ec426532b2
21 changed files with 770 additions and 846 deletions

View file

@ -103,6 +103,10 @@ SubstringAssertion NISnetgrouptriple Bootparameter
.RE
.RE
.TP
.B concurrency <integer>
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

View file

@ -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 <lwp/lwp.h>
#include <lwp/stackdep.h>
#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 <process.h>
#include <windows.h>
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_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 );
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 ));
#ifndef LDAP_THREAD_HAVE_TPOOL
typedef struct ldap_int_thread_pool_s * ldap_int_thread_pool_t;
#endif
#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 ));
#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 */

View file

@ -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

View file

@ -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

View file

@ -19,7 +19,9 @@
#include <ac/errno.h>
#include <ac/string.h>
#include <ac/time.h>
#include "ldap-int.h"
#include "ldap_pvt_thread.h"
/*
@ -29,12 +31,27 @@
*/
#ifndef LDAP_THREAD_HAVE_RDWR
int
ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
{
assert( rw != NULL );
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;
};
memset( rw, '\0', sizeof(ldap_pvt_thread_rdwr_t) );
int
ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rwlock )
{
struct ldap_int_thread_rdwr_s *rw;
assert( rwlock != NULL );
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 );

View file

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

View file

@ -35,7 +35,7 @@
#include "ldap-int.h"
#include "ldap_int_thread.h"
#include "ldap_pvt_thread.h"
#include <lwp/lwp.h>
#include <lwp/stackdep.h>
@ -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 );
}

View file

@ -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;

View file

@ -18,26 +18,23 @@
#include <ac/errno.h>
#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 );
}

View file

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

View file

@ -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 <stdio.h>
#include <ac/stdlib.h>
#include <ac/unistd.h> /* 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 */

View file

@ -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 */

View file

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

View file

@ -17,527 +17,71 @@
#include <ac/stdlib.h>
#include <ac/string.h>
#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);
}
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 )
unsigned int
ldap_pvt_thread_sleep(
unsigned int interval
)
{
return(0);
sleep( interval );
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 )
{
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

396
libraries/libldap_r/tpool.c Normal file
View file

@ -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 <stdio.h>
#include <stdarg.h>
#include <ac/stdlib.h>
#include <ac/string.h>
#include <ac/time.h>
#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 */

View file

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

View file

@ -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 <level>\" 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 <level>\" 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 ) {

View file

@ -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,

View file

@ -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;
}

View file

@ -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( &currenttime_mutex );
ldap_pvt_thread_mutex_init( &entry2str_mutex );

View file

@ -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 );