Commit ec426532 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

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.
parent 1bfcb4b0
......@@ -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
......
......@@ -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_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 */
......@@ -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
......
......@@ -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
......
......@@ -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
struct ldap_int_thread_rdwr_s {
ldap_pvt_thread_mutex_t ltrw_mutex;
ldap_pvt_thread_cond_t ltrw_read; /* wait for read */
ldap_pvt_thread_cond_t ltrw_write; /* wait for write */
int ltrw_valid;
#define LDAP_PVT_THREAD_RDWR_VALID 0x0bad
int ltrw_r_active;
int ltrw_w_active;
int ltrw_r_wait;
int ltrw_w_wait;
};
int
ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rwlock )
{
assert( rw != NULL );
struct ldap_int_thread_rdwr_s *rw;
assert( rwlock != NULL );
memset( rw, '\0', sizeof(ldap_pvt_thread_rdwr_t) );
rw = (struct ldap_int_thread_rdwr_s *) LDAP_CALLOC( 1,
sizeof( struct ldap_int_thread_rdwr_s ) );
/* we should check return results */
ldap_pvt_thread_mutex_init( &rw->ltrw_mutex );
......@@ -42,12 +59,19 @@ ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
ldap_pvt_thread_cond_init( &rw->ltrw_write );
rw->ltrw_valid = LDAP_PVT_THREAD_RDWR_VALID;
*rwlock = rw;
return 0;
}
int
ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rwlock )
{
struct ldap_int_thread_rdwr_s *rw;
assert( rwlock != NULL );
rw = *rwlock;
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
......@@ -76,11 +100,18 @@ ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
ldap_pvt_thread_cond_destroy( &rw->ltrw_read );
ldap_pvt_thread_cond_destroy( &rw->ltrw_write );
LDAP_FREE(rw);
*rwlock = NULL;
return 0;
}
int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rwlock )
{
struct ldap_int_thread_rdwr_s *rw;
assert( rwlock != NULL );
rw = *rwlock;
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
......@@ -109,8 +140,13 @@ int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
return 0;
}
int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rwlock )
{
struct ldap_int_thread_rdwr_s *rw;
assert( rwlock != NULL );
rw = *rwlock;
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
......@@ -131,8 +167,13 @@ int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
return 0;
}
int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rwlock )
{
struct ldap_int_thread_rdwr_s *rw;
assert( rwlock != NULL );
rw = *rwlock;
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
......@@ -152,8 +193,13 @@ int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
return 0;
}
int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rwlock )
{
struct ldap_int_thread_rdwr_s *rw;
assert( rwlock != NULL );
rw = *rwlock;
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
......@@ -180,8 +226,13 @@ int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
return 0;
}
int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rwlock )
{
struct ldap_int_thread_rdwr_s *rw;
assert( rwlock != NULL );
rw = *rwlock;
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
......@@ -202,8 +253,13 @@ int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
return 0;
}
int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rwlock )
{
struct ldap_int_thread_rdwr_s *rw;
assert( rwlock != NULL );
rw = *rwlock;
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
......@@ -238,24 +294,39 @@ int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
* a lock are caught.
*/
int ldap_pvt_thread_rdwr_readers(ldap_pvt_thread_rdwr_t *rw)
int ldap_pvt_thread_rdwr_readers(ldap_pvt_thread_rdwr_t *rwlock)
{
struct ldap_int_thread_rdwr_s *rw;
assert( rwlock != NULL );
rw = *rwlock;
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
return( rw->ltrw_r_active );
}
int ldap_pvt_thread_rdwr_writers(ldap_pvt_thread_rdwr_t *rw)
int ldap_pvt_thread_rdwr_writers(ldap_pvt_thread_rdwr_t *rwlock)
{
struct ldap_int_thread_rdwr_s *rw;
assert( rwlock != NULL );
rw = *rwlock;
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
return( rw->ltrw_w_active );
}
int ldap_pvt_thread_rdwr_active(ldap_pvt_thread_rdwr_t *rw)
int ldap_pvt_thread_rdwr_active(ldap_pvt_thread_rdwr_t *rwlock)
{
struct ldap_int_thread_rdwr_s *rw;
assert( rwlock != NULL );
rw = *rwlock;
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
......
......@@ -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 );
}
......
......@@ -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,
}