getdn.c getentry.c getattr.c getvalues.c addentry.c \
request.c getdxbyname.c os-ip.c url.c charset.c \
init.c options.c strdup.c util-int.c
+SRCS = thr_posix.c thr_cthreads.c thr_thr.c thr_lwp.c thr_nt.c \
+ thr_stub.c rdwr.c
OBJS = 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 sbind.lo kbind.lo unbind.lo friendly.lo cldap.lo \
free.lo disptmpl.lo srchpref.lo dsparse.lo tmplout.lo sort.lo \
getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
request.lo getdxbyname.lo os-ip.lo url.lo charset.lo \
- init.lo options.lo strdup.lo util-int.lo
+ init.lo options.lo strdup.lo util-int.lo \
+ thr_posix.lo thr_cthreads.lo thr_thr.lo thr_lwp.lo thr_nt.lo \
+ thr_stub.lo rdwr.lo
LDAP_INCDIR= ../../include
LDAP_LIBDIR= ../../libraries
--- /dev/null
+/*
+** This basic implementation of Reader/Writer locks does not
+** protect writers from starvation. That is, if a writer is
+** currently waiting on a reader, any new reader will get
+** the lock before the writer.
+*/
+
+/********************************************************
+ * An example source module to accompany...
+ *
+ * "Using POSIX Threads: Programming with Pthreads"
+ * by Brad nichols, Dick Buttlar, Jackie Farrell
+ * O'Reilly & Associates, Inc.
+ *
+ ********************************************************
+ * rdwr.c --
+ *
+ * Library of functions implementing reader/writer locks
+ */
+
+#include "portable.h"
+
+#include <stdlib.h>
+
+#include "ldap_pvt_thread.h"
+
+int
+ldap_pvt_thread_rdwr_init(ldap_pvt_thread_rdwr_t *rdwrp,
+ ldap_pvt_thread_rdwrattr_t *attrp)
+{
+ rdwrp->readers_reading = 0;
+ rdwrp->writer_writing = 0;
+ ldap_pvt_thread_mutex_init(&(rdwrp->mutex), NULL );
+ ldap_pvt_thread_cond_init(&(rdwrp->lock_free), NULL );
+ return 0;
+}
+
+int ldap_pvt_thread_rdwr_rlock(ldap_pvt_thread_rdwr_t *rdwrp){
+ ldap_pvt_thread_mutex_lock(&(rdwrp->mutex));
+ while(rdwrp->writer_writing) {
+ ldap_pvt_thread_cond_wait(&(rdwrp->lock_free),
+ &(rdwrp->mutex));
+ }
+ rdwrp->readers_reading++;
+ ldap_pvt_thread_mutex_unlock(&(rdwrp->mutex));
+ return 0;
+}
+
+int ldap_pvt_thread_rdwr_runlock(ldap_pvt_thread_rdwr_t *rdwrp)
+{
+ ldap_pvt_thread_mutex_lock(&(rdwrp->mutex));
+ if (rdwrp->readers_reading == 0) {
+ ldap_pvt_thread_mutex_unlock(&(rdwrp->mutex));
+ return -1;
+ }
+ else {
+ rdwrp->readers_reading--;
+ if (rdwrp->readers_reading == 0) {
+ ldap_pvt_thread_cond_signal(&(rdwrp->lock_free));
+ }
+ ldap_pvt_thread_mutex_unlock(&(rdwrp->mutex));
+ return 0;
+ }
+}
+
+int ldap_pvt_thread_rdwr_wlock(ldap_pvt_thread_rdwr_t *rdwrp)
+{
+ ldap_pvt_thread_mutex_lock(&(rdwrp->mutex));
+ while(rdwrp->writer_writing || rdwrp->readers_reading) {
+ ldap_pvt_thread_cond_wait(&(rdwrp->lock_free),
+ &(rdwrp->mutex));
+ }
+ rdwrp->writer_writing++;
+ ldap_pvt_thread_mutex_unlock(&(rdwrp->mutex));
+ return 0;
+}
+
+int ldap_pvt_thread_rdwr_wunlock(ldap_pvt_thread_rdwr_t *rdwrp)
+{
+ ldap_pvt_thread_mutex_lock(&(rdwrp->mutex));
+ if (rdwrp->writer_writing == 0) {
+ ldap_pvt_thread_mutex_unlock(&(rdwrp->mutex));
+ return -1;
+ }
+ else {
+ rdwrp->writer_writing = 0;
+ ldap_pvt_thread_cond_broadcast(&(rdwrp->lock_free));
+ ldap_pvt_thread_mutex_unlock(&(rdwrp->mutex));
+ return 0;
+ }
+}
+
+#ifdef LDAP_DEBUG
+
+/* just for testing,
+ * return 0 if false, suitable for assert(ldap_pvt_thread_rdwr_Xchk(rdwr))
+ *
+ * Currently they don't check if the calling thread is the one
+ * that has the lock, just that there is a reader or writer.
+ *
+ * Basically sufficent for testing that places that should have
+ * a lock are caught.
+ */
+
+int ldap_pvt_thread_rdwr_rchk(ldap_pvt_thread_rdwr_t *rdwrp)
+{
+ return(rdwrp->readers_reading!=0);
+}
+
+int ldap_pvt_thread_rdwr_wchk(ldap_pvt_thread_rdwr_t *rdwrp)
+{
+ return(rdwrp->writer_writing!=0);
+}
+int ldap_pvt_thread_rdwr_rwchk(ldap_pvt_thread_rdwr_t *rdwrp)
+{
+ return(ldap_pvt_thread_rdwr_rchk_np(rdwrp) ||
+ ldap_pvt_thread_rdwr_wchk_np(rdwrp));
+}
+
+#endif /* LDAP_DEBUG */
--- /dev/null
+/* thrmach.c - wrapper for mach cthreads */
+
+#include "portable.h"
+#include "ldap_pvt_thread.h"
+
+#if defined( HAVE_MACH_CTHREADS )
+
+/***********************************************************************
+ * *
+ * under NEXTSTEP or OPENSTEP use CThreads *
+ * lukeh@xedoc.com.au *
+ * *
+ ***********************************************************************/
+
+int
+ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
+ ldap_pvt_thread_attr_t *attr,
+ void *(*start_routine)( void *), void *arg)
+{
+ *thread = cthread_fork( (cthread_fn_t) start_routine, arg);
+ return ( *thread == NULL ? -1 : 0 );
+}
+
+void
+ldap_pvt_thread_exit( void *retval )
+{
+ cthread_exit( (any_t) retval );
+}
+
+int
+ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
+{
+ void *status;
+ status = (void *) cthread_join ( tid );
+ if (thread_return != NULL)
+ {
+ *thread_return = status;
+ }
+ return 0;
+}
+
+int
+ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
+{
+ return 0;
+}
+
+int
+ldap_pvt_thread_yield( void )
+{
+ cthread_yield();
+ return 0;
+}
+
+int
+ldap_pvt_thread_attr_init( ldap_pvt_thread_attr_t *attr )
+{
+ *attr = 0;
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_attr_destroy( ldap_pvt_thread_attr_t *attr )
+{
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_attr_setdetachstate( ldap_pvt_thread_attr_t *attr, int dstate )
+{
+ *attr = dstate;
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond,
+ ldap_pvt_thread_condattr_t *attr )
+{
+ condition_init( cond );
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
+{
+ condition_signal( cond );
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cv )
+{
+ condition_broadcast( cv );
+ return( 0 );
+}
+
+int
+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_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex,
+ ldap_pvt_thread_mutexattr_t *attr )
+{
+ mutex_init( mutex );
+ mutex->name = NULL;
+ return ( 0 );
+}
+
+int
+ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
+{
+ mutex_clear( mutex );
+ return ( 0 );
+}
+
+int
+ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
+{
+ mutex_lock( mutex );
+ return ( 0 );
+}
+
+int
+ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
+{
+ mutex_unlock( mutex );
+ return ( 0 );
+}
+
+int
+ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
+{
+ return mutex_try_lock( mutex );
+}
+
+#endif /* HAVE_MACH_CTHREADS */
--- /dev/null
+/* thrsunos.c - wrappers around SunOS LWP threads */
+
+/* BUGS:
+ * - slurpd calls the get_stack/free_stack functions. Should be fixed, so
+ * they can become static.
+ */
+
+#include "portable.h"
+#include "ldap_pvt_thread.h"
+
+#if defined( HAVE_LWP )
+
+/*************
+ * *
+ * SunOS LWP *
+ * *
+ *************/
+#include <stdio.h>
+
+#include <ac/time.h>
+#include <ac/socket.h>
+
+#include "lber.h"
+#include "ldap.h"
+#include "ldap_log.h"
+
+#include <lwp/lwp.h>
+#include <lwp/stackdep.h>
+
+#define MAX_STACK 51200
+#define MAX_THREADS 20
+
+struct stackinfo {
+ int stk_inuse;
+ stkalign_t *stk_stack;
+};
+
+static struct stackinfo *stacks;
+
+stkalign_t * ldap_pvt_thread_get_stack( int *stacknop )
+{
+ int i;
+
+ if ( stacks == NULL ) {
+ stacks = (struct stackinfo *) ch_calloc( 1, MAX_THREADS *
+ sizeof(struct stackinfo) );
+ }
+
+ for ( i = 0; i < MAX_THREADS; i++ ) {
+ if ( stacks[i].stk_inuse == 0 ) {
+ break;
+ }
+ }
+
+ if ( i == MAX_THREADS ) {
+ Debug( LDAP_DEBUG_ANY,
+ "no more stacks (max %d) - increase MAX_THREADS for more",
+ MAX_THREADS, 0, 0 );
+ return( NULL );
+ }
+
+ if ( stacks[i].stk_stack == NULL ) {
+ stacks[i].stk_stack = (stkalign_t *) malloc(
+ (MAX_STACK / sizeof(stkalign_t) + 1 )
+ * sizeof(stkalign_t) );
+ }
+
+ *stacknop = i;
+ stacks[i].stk_inuse = 1;
+ return( stacks[i].stk_stack + MAX_STACK / sizeof(stkalign_t) );
+}
+
+void
+ldap_pvt_thread_free_stack( int stackno )
+{
+ if ( stackno < 0 || stackno > MAX_THREADS ) {
+ Debug( LDAP_DEBUG_ANY, "free_stack of bogus stack %d",
+ stackno, 0, 0 );
+ }
+
+ stacks[stackno].stk_inuse = 0;
+}
+
+static void
+lwp_create_stack( void *(*func)(), void *arg, int stackno )
+{
+ (*func)( arg );
+
+ ldap_pvt_thread_free_stack( stackno );
+}
+
+int
+ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
+ ldap_pvt_thread_attr_t *attr,
+ void *(*start_routine)( void *), void *arg)
+{
+ stkalign_t *stack;
+ int stackno;
+
+ if ( (stack = ldap_pvt_thread_get_stack( &stackno )) == NULL ) {
+ return( -1 );
+ }
+ return( lwp_create( thread, lwp_create_stack, MINPRIO, 0,
+ stack, 3, start_routine, arg, stackno ) );
+}
+
+void
+ldap_pvt_thread_exit( void *retval )
+{
+ lwp_destroy( SELF );
+}
+
+int
+ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
+{
+ lwp_join( thread );
+ return 0;
+}
+
+int
+ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
+{
+ return 0;
+}
+
+int
+ldap_pvt_thread_yield( void )
+{
+ lwp_yield( SELF );
+ return 0;
+}
+
+int
+ldap_pvt_thread_attr_init( ldap_pvt_thread_attr_t *attr )
+{
+ *attr = 0;
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_attr_destroy( ldap_pvt_thread_attr_t *attr )
+{
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_attr_setdetachstate( ldap_pvt_thread_attr_t *attr, int dstate )
+{
+ *attr = dstate;
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_attr_getdetachstate( pthread_attr_t *attr, int *detachstate )
+{
+ *detachstate = *attr;
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond,
+ ldap_pvt_thread_condattr_t *attr )
+{
+ /*
+ * lwp cv_create requires the monitor id be passed in
+ * when the cv is created, pthreads passes it when the
+ * condition is waited for. so, we fake the creation
+ * here and actually do it when the cv is waited for
+ * later.
+ */
+
+ cond->lcv_created = 0;
+
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
+{
+ return( cond->lcv_created ? cv_notify( cv->lcv_cv ) : 0 );
+}
+
+int
+ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond,
+ ldap_pvt_thread_mutex_t *mutex )
+{
+ if ( ! cond->lcv_created ) {
+ cv_create( &cond->lcv_cv, *mutex );
+ cond->lcv_created = 1;
+ }
+
+ return( cv_wait( cond->lcv_cv ) );
+}
+
+int
+ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex,
+ ldap_pvt_thread_mutexattr_t *attr )
+{
+ return( mon_create( mutex ) );
+}
+
+int
+ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
+{
+ return( mon_destroy( *mutex ) );
+}
+
+int
+ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
+{
+ return( mon_enter( *mutex ) );
+}
+
+int
+ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
+{
+ return( mon_exit( *mutex ) );
+}
+
+int
+ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp )
+{
+ return( mon_cond_enter( *mp ) );
+}
+
+int
+ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv )
+{
+ return( cv->lcv_created ? cv_destroy( cv->lcv_cv ) : 0 );
+}
+
+int
+ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cv )
+{
+ return( cv->lcv_created ? cv_broadcast( cv->lcv_cv ) : 0 );
+}
+
+#endif /* HAVE_LWP */
--- /dev/null
+/* thrnt.c - wrapper around NT threads */
+
+#include "portable.h"
+#include "ldap_pvt_thread.h"
+
+#if defined( HAVE_NT_THREADS )
+
+int
+openldap_thread_create( openldap_thread_t * thread,
+ openldap_thread_attr_t *attr,
+ void *(*start_routine)( void *), void *arg)
+{
+ *thread = (openldap_thread_t)_beginthread( (void *) start_routine,
+ 0, arg );
+ return ( (unsigned long)*thread == -1 ? -1 : 0 );
+}
+
+void
+openldap_thread_exit( void *retval )
+{
+ _endthread( );
+}
+
+int
+openldap_thread_join( openldap_thread_t thread, void **thread_return )
+{
+ DWORD status;
+ status = WaitForSingleObject( thread, INFINITE );
+ if (status == WAIT_FAILED) {
+ return -1;
+ }
+ return 0;
+}
+
+int
+openldap_thread_kill( openldap_thread_t thread, int signo )
+{
+ return 0;
+}
+
+int
+openldap_thread_yield( void )
+{
+ return 0;
+}
+
+int
+openldap_thread_attr_init( openldap_thread_attr_t *attr )
+{
+ *attr = 0;
+ return( 0 );
+}
+
+int
+openldap_thread_attr_destroy( openldap_thread_attr_t *attr )
+{
+ return( 0 );
+}
+
+int
+openldap_thread_attr_setdetachstate( openldap_thread_attr_t *attr, int dstate )
+{
+ *attr = dstate;
+ return( 0 );
+}
+
+int
+openldap_thread_attr_getdetachstate( openldap_thread_attr_t *attr,
+ int *detachstate )
+{
+ *detachstate = *attr;
+ return( 0 );
+}
+
+int
+openldap_thread_cond_init( openldap_thread_cond_t *cond,
+ openldap_thread_condattr_t *attr )
+{
+ *cond = CreateEvent( NULL, FALSE, FALSE, NULL );
+ return( 0 );
+}
+
+int
+openldap_thread_cond_destroy( openldap_thread_cond_t *cv )
+{
+ CloseHandle( *cv );
+ return( 0 );
+}
+
+int
+openldap_thread_cond_signal( openldap_thread_cond_t *cond )
+{
+ SetEvent( *cond );
+ return( 0 );
+}
+
+int
+openldap_thread_cond_wait( openldap_thread_cond_t *cond,
+ openldap_thread_mutex_t *mutex )
+{
+ ReleaseMutex( *mutex );
+ WaitForSingleObject( *cond, INFINITE );
+ WaitForSingleObject( *mutex, INFINITE );
+ return( 0 );
+}
+
+int
+openldap_thread_cond_broadcast( openldap_thread_cond_t *cv )
+{
+ SetEvent( *cv );
+ return( 0 );
+}
+
+int
+openldap_thread_mutex_init( openldap_thread_mutex_t *mutex,
+ openldap_thread_mutexattr_t *attr )
+{
+ *mutex = CreateMutex( NULL, 0, NULL );
+ return ( 0 );
+}
+
+int
+openldap_thread_mutex_destroy( openldap_thread_mutex_t *mutex )
+{
+ CloseHandle( *mutex );
+ return ( 0 );
+}
+
+int
+openldap_thread_mutex_lock( openldap_thread_mutex_t *mutex )
+{
+ WaitForSingleObject( *mutex, INFINITE );
+ return ( 0 );
+}
+
+int
+openldap_thread_mutex_unlock( openldap_thread_mutex_t *mutex )
+{
+ ReleaseMutex( *mutex );
+ return ( 0 );
+}
+
+int
+openldap_thread_mutex_trylock( openldap_thread_mutex_t *mp )
+{
+ DWORD status;
+
+ status = WaitForSingleObject( *mp, 0 );
+ if ( (status == WAIT_FAILED) || (status == WAIT_TIMEOUT) )
+ return 0;
+ else
+ return 1;
+}
+
+#endif
--- /dev/null
+/* thrposix.c - wrapper around posix and posixish thread implementations.
+ */
+
+#include "portable.h"
+#include "ldap_pvt_thread.h"
+
+#if defined( HAVE_PTHREADS )
+
+int
+ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
+ ldap_pvt_thread_attr_t *attr,
+ void *(*start_routine)( void *), void *arg)
+{
+#if !defined( HAVE_PTHREADS_D4 )
+ /* This is a standard pthreads implementation. */
+ return pthread_create( thread, attr, start_routine, arg );
+#else
+ /* This is a draft 4 or earlier implementation. */
+ return pthread_create( thread, *attr, start_routine, arg );
+#endif
+}
+
+void
+ldap_pvt_thread_exit( void *retval )
+{
+ pthread_exit( retval );
+}
+
+int
+ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
+{
+#if !defined( HAVE_PTHREADS_FINAL )
+ void *dummy;
+ if (thread_return==NULL)
+ thread_return=&dummy;
+#endif
+ return pthread_join( thread, thread_return );
+}
+
+int
+ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
+{
+#ifdef HAVE_PTHREAD_KILL
+ return pthread_kill( thread, signo );
+#else
+ /* pthread package with DCE */
+ if (kill( getpid(), sig )<0)
+ return errno;
+ return 0;
+#endif
+}
+
+int
+ldap_pvt_thread_yield( void )
+{
+#ifdef HAVE_SCHED_YIELD
+ return sched_yield();
+#else
+ return pthread_yield();
+#endif
+}
+
+int
+ldap_pvt_thread_attr_init( ldap_pvt_thread_attr_t *attr )
+{
+#if defined( HAVE_PTHREAD_ATTR_INIT )
+ return pthread_attr_init( attr );
+#elif defined( HAVE_PTHREAD_ATTR_CREATE )
+ return pthread_attr_create( attr );
+#else
+ No way to init attr, so cause an error.
+#endif
+}
+
+int
+ldap_pvt_thread_attr_destroy( ldap_pvt_thread_attr_t *attr )
+{
+#if defined( HAVE_PTHREAD_ATTR_DESTROY )
+ return pthread_attr_destroy( attr );
+#elif defined( HAVE_PTHREAD_ATTR_DELETE )
+ return pthread_attr_delete( attr );
+#else
+ No way to destroy attr, so cause an error.
+#endif
+}
+
+int
+ldap_pvt_thread_attr_setdetachstate( ldap_pvt_thread_attr_t *attr, int dstate )
+{
+#if defined( HAVE_PTHREAD_ATTR_SETDETACHSTATE )
+ return pthread_attr_setdetachstate( attr, dstate );
+#elif defined( HAVE_PTHREAD_ATTR_SETDETACH_NP )
+ return pthread_attr_setdetach_np( attr, dstate );
+#else
+ No way to set state, so cause an error.
+#endif
+}
+
+int
+ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond,
+ ldap_pvt_thread_condattr_t *attr )
+{
+#if defined( HAVE_PTHREADS_D4 )
+ return pthread_cond_init( cond,
+ attr ? attr : pthread_condattr_default );
+#else
+ return pthread_cond_init( cond, attr );
+#endif
+}
+
+int
+ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
+{
+ return pthread_cond_signal( cond );
+}
+
+int
+ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
+{
+ return pthread_cond_broadcast( cond );
+}
+
+int
+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_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex,
+ ldap_pvt_thread_mutexattr_t *attr )
+{
+#if defined( HAVE_PTHREADS_D4 )
+ return pthread_mutex_init( mutex,
+ attr ? attr : pthread_mutexattr_default );
+#else
+ return pthread_mutex_init( mutex, attr );
+#endif
+}
+
+int
+ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
+{
+ return pthread_mutex_destroy( mutex );
+}
+
+int
+ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
+{
+ return pthread_mutex_lock( mutex );
+}
+
+int
+ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
+{
+ return pthread_mutex_unlock( mutex );
+}
+
+#endif /* HAVE_PTHREADS */
+
--- /dev/null
+/* thrstub.c - stubs for the threads */
+
+#include "portable.h"
+#include "ldap_pvt_thread.h"
+
+#if defined( NO_THREADS )
+
+/***********************************************************************
+ * *
+ * no threads package defined for this system - fake ok returns from *
+ * all threads routines (making it single-threaded). *
+ * *
+ ***********************************************************************/
+
+int
+openldap_thread_create( openldap_thread_t * thread,
+ openldap_thread_attr_t *attr,
+ void *(*start_routine)( void *), void *arg)
+{
+ start_routine( arg );
+ return 0;
+}
+
+void
+openldap_thread_exit( void *retval )
+{
+ return;
+}
+
+int
+openldap_thread_join( openldap_thread_t thread, void **thread_return )
+{
+ return 0;
+}
+
+int
+openldap_thread_kill( openldap_thread_t thread, int signo )
+{
+ return 0;
+}
+
+int
+openldap_thread_yield( void )
+{
+ return 0;
+}
+
+int
+openldap_thread_attr_init( openldap_thread_attr_t *attr )
+{
+ return 0;
+}
+
+int
+openldap_thread_attr_destroy( openldap_thread_attr_t *attr )
+{
+ return 0;
+}
+
+int
+openldap_thread_attr_setdetachstate( openldap_thread_attr_t *attr, int dstate )
+{
+ return 0;
+}
+
+int
+openldap_thread_cond_init( openldap_thread_cond_t *cond,
+ openldap_thread_condattr_t *attr )
+{
+ return 0;
+}
+
+int
+openldap_thread_cond_signal( openldap_thread_cond_t *cond )
+{
+ return 0;
+}
+
+int
+openldap_thread_cond_wait( openldap_thread_cond_t *cond,
+ openldap_thread_mutex_t *mutex )
+{
+ return 0;
+}
+
+int
+openldap_thread_mutex_init( openldap_thread_mutex_t *mutex,
+ openldap_thread_mutexattr_t *attr )
+{
+ return 0;
+}
+
+int
+openldap_thread_mutex_destroy( openldap_thread_mutex_t *mutex )
+{
+ return 0;
+}
+
+int
+openldap_thread_mutex_lock( openldap_thread_mutex_t *mutex )
+{
+ return 0;
+}
+
+int
+openldap_thread_mutex_unlock( openldap_thread_mutex_t *mutex )
+{
+ return 0;
+}
+
+#endif /* NO_THREADS */
--- /dev/null
+/* thrsolaris.c - wrappers around solaris threads */
+
+#include "portable.h"
+#include "ldap_pvt_thread.h"
+
+#if defined( HAVE_THR )
+
+/*******************
+ * *
+ * Solaris Threads *
+ * *
+ *******************/
+
+int
+ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
+ ldap_pvt_thread_attr_t *attr,
+ void *(*start_routine)( void *), void *arg)
+{
+ return( thr_create( NULL, 0, start_routine, arg, *attr, thread ) );
+}
+
+void
+ldap_pvt_thread_exit( void *retval )
+{
+ thr_exit( NULL );
+}
+
+int ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
+{
+ thr_join( thread, NULL, thread_return );
+ return 0;
+}
+
+int
+ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
+{
+ thr_kill( thread, signo );
+ return 0;
+}
+
+int
+ldap_pvt_thread_yield( void )
+{
+ thr_yield();
+ return 0;
+}
+
+int
+ldap_pvt_thread_attr_init( ldap_pvt_thread_attr_t *attr )
+{
+ *attr = 0;
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_attr_destroy( ldap_pvt_thread_attr_t *attr )
+{
+ *attr = 0;
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_attr_setdetachstate( ldap_pvt_thread_attr_t *attr, int dstate )
+{
+ *attr = detachstate;
+ return( 0 );
+}
+
+int
+ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond,
+ ldap_pvt_thread_condattr_t *attr )
+{
+ return( cond_init( cond, attr ? *attr : USYNC_THREAD, NULL ) );
+}
+
+int
+ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
+{
+ return( cond_signal( cond ) );
+}
+
+int
+ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cv )
+{
+ return( cond_broadcast( cv ) );
+}
+
+int
+ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond,
+ ldap_pvt_thread_mutex_t *mutex )
+{
+ return( cond_wait( cond, mutex ) );
+}
+
+int
+ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cv )
+{
+ return( cond_destroy( cv ) );
+}
+
+int
+ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex,
+ ldap_pvt_thread_mutexattr_t *attr )
+{
+ return( mutex_init( mutex, attr ? *attr : USYNC_THREAD, NULL ) );
+}
+
+int
+ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
+{
+ return( mutex_destroy( mutex ) );
+}
+
+int
+ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
+{
+ return( mutex_lock( mutex ) );
+}
+
+int
+ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
+{
+ return( mutex_unlock( mutex ) );
+}
+
+int
+ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp )
+{
+ return( mutex_trylock( mp ) );
+}
+
+#endif /* HAVE_THR */