]> git.sur5r.net Git - openldap/commitdiff
Changes to support threads from libldap_r.
authorBart Hartgers <bart@openldap.org>
Fri, 15 Jan 1999 14:54:25 +0000 (14:54 +0000)
committerBart Hartgers <bart@openldap.org>
Fri, 15 Jan 1999 14:54:25 +0000 (14:54 +0000)
libraries/libldap_r/Makefile.in
libraries/libldap_r/rdwr.c [new file with mode: 0644]
libraries/libldap_r/thr_cthreads.c [new file with mode: 0644]
libraries/libldap_r/thr_lwp.c [new file with mode: 0644]
libraries/libldap_r/thr_nt.c [new file with mode: 0644]
libraries/libldap_r/thr_posix.c [new file with mode: 0644]
libraries/libldap_r/thr_stub.c [new file with mode: 0644]
libraries/libldap_r/thr_thr.c [new file with mode: 0644]

index f27e9eeef277d298115056efa838ff2150dc13ae..1713c05071bc842cd9ef8b2aa35d1f9e6b99970c 100644 (file)
@@ -15,13 +15,17 @@ XXSRCS      = apitest.c test.c tmpltest.c \
        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
diff --git a/libraries/libldap_r/rdwr.c b/libraries/libldap_r/rdwr.c
new file mode 100644 (file)
index 0000000..5e64143
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+** 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 */
diff --git a/libraries/libldap_r/thr_cthreads.c b/libraries/libldap_r/thr_cthreads.c
new file mode 100644 (file)
index 0000000..8a308e7
--- /dev/null
@@ -0,0 +1,141 @@
+/* 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 */
diff --git a/libraries/libldap_r/thr_lwp.c b/libraries/libldap_r/thr_lwp.c
new file mode 100644 (file)
index 0000000..349bdfc
--- /dev/null
@@ -0,0 +1,238 @@
+/* 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 */
diff --git a/libraries/libldap_r/thr_nt.c b/libraries/libldap_r/thr_nt.c
new file mode 100644 (file)
index 0000000..8592ce6
--- /dev/null
@@ -0,0 +1,155 @@
+/* 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
diff --git a/libraries/libldap_r/thr_posix.c b/libraries/libldap_r/thr_posix.c
new file mode 100644 (file)
index 0000000..9bd2b0a
--- /dev/null
@@ -0,0 +1,161 @@
+/* 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 */
+
diff --git a/libraries/libldap_r/thr_stub.c b/libraries/libldap_r/thr_stub.c
new file mode 100644 (file)
index 0000000..b70cec1
--- /dev/null
@@ -0,0 +1,111 @@
+/* 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 */
diff --git a/libraries/libldap_r/thr_thr.c b/libraries/libldap_r/thr_thr.c
new file mode 100644 (file)
index 0000000..5b2e6d4
--- /dev/null
@@ -0,0 +1,132 @@
+/* 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 */