mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-24 16:49:39 -05:00
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:
parent
1bfcb4b039
commit
ec426532b2
21 changed files with 770 additions and 846 deletions
|
|
@ -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_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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
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 );
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
|||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 ) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
396
libraries/libldap_r/tpool.c
Normal 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 */
|
||||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ char **g_argv;
|
|||
* global variables that need mutex protection
|
||||
*/
|
||||
ldap_pvt_thread_pool_t connection_pool;
|
||||
|
||||
ldap_pvt_thread_mutex_t gmtime_mutex;
|
||||
#ifdef SLAPD_CRYPT
|
||||
ldap_pvt_thread_mutex_t crypt_mutex;
|
||||
|
|
@ -94,7 +93,8 @@ slap_init( int mode, const char *name )
|
|||
slap_name = name;
|
||||
|
||||
(void) ldap_pvt_thread_initialize();
|
||||
ldap_pvt_thread_pool_initialize(&connection_pool, 0, 0);
|
||||
|
||||
ldap_pvt_thread_pool_init(&connection_pool, 0, 0);
|
||||
|
||||
ldap_pvt_thread_mutex_init( ¤ttime_mutex );
|
||||
ldap_pvt_thread_mutex_init( &entry2str_mutex );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
Loading…
Reference in a new issue