.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
#ifndef _LDAP_INT_THREAD_H
#define _LDAP_INT_THREAD_H
-#include "ldap_cdefs.h"
-
#if defined( HAVE_PTHREADS )
/**********************************
* *
#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 )
LDAP_END_DECL
-
#elif defined( HAVE_THR )
/********************************************
* *
#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
#include <lwp/lwp.h>
#include <lwp/stackdep.h>
+#define LDAP_THREAD_HAVE_SLEEP 1
LDAP_BEGIN_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;
* *
***********************************/
-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 */
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 ));
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 ));
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 )
#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
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 \
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
#include <ac/errno.h>
#include <ac/string.h>
+#include <ac/time.h>
+#include "ldap-int.h"
#include "ldap_pvt_thread.h"
/*
*/
#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 );
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 );
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 );
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 );
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 );
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 );
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 );
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 );
* 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 );
#include "portable.h"
#if defined( HAVE_MACH_CTHREADS )
-#include "ldap_int_thread.h"
+#include "ldap_pvt_thread.h"
/***********************************************************************
* *
}
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)
{
}
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 );
}
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;
}
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 );
}
#include "ldap-int.h"
-#include "ldap_int_thread.h"
+#include "ldap_pvt_thread.h"
#include <lwp/lwp.h>
#include <lwp/stackdep.h>
}
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)
}
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
)
{
}
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
}
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 );
}
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 );
}
#if defined( HAVE_NT_THREADS )
-#include "ldap_int_thread.h"
+#include "ldap_pvt_thread.h"
int
ldap_int_thread_initialize( 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 );
}
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 );
}
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;
#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;
}
#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 );
#ifdef HAVE_PTHREAD_GETCONCURRENCY
int
-ldap_int_thread_get_concurrency(void)
+ldap_pvt_thread_get_concurrency(void)
{
#ifdef HAVE_PTHREAD_GETCONCURRENCY
return pthread_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)
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
}
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;
}
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 );
}
int
-ldap_int_thread_yield( void )
+ldap_pvt_thread_yield( void )
{
#ifdef _POSIX_THREAD_IS_GNU_PTH
sched_yield();
}
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 );
}
#if defined( HAVE_GNU_PTH )
-#include "ldap_int_thread.h"
+#include "ldap_pvt_thread.h"
/*******************
* *
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
}
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)
}
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 ) );
}
+++ /dev/null
-/* $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 */
#if defined( NO_THREADS )
-#include "ldap_int_thread.h"
+#include "ldap_pvt_thread.h"
/***********************************************************************
* *
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)
}
void
-ldap_int_thread_exit( void *retval )
+ldap_pvt_thread_exit( void *retval )
{
if( retval != NULL ) {
ldap_int_status = 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 */
#if defined( HAVE_THR )
-#include "ldap_int_thread.h"
+#include "ldap_pvt_thread.h"
/*******************
* *
int
ldap_int_thread_initialize( void )
{
-#ifdef LDAP_THREAD_CONCURRENCY
- thr_setconcurrency( LDAP_THREAD_CONCURRENCY );
-#endif
return 0;
}
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)
}
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 ) );
}
#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);
}
+#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
--- /dev/null
+/* $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 */
}
}
-#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 );
}
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 ) {
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,
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;
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;
}
* 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;
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 );
}
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 );