dnl ====================================================================
dnl Check POSIX Thread version
dnl
-dnl defines ol_cv_posix_version to 'final' or 'draft' or 'unknown'
-dnl 'unknown' implies that the version could not be detected
-dnl or that pthreads.h does exist. Existance of pthreads.h
+dnl defines ol_cv_pthread_version to 0, 4, 5, 6, 7, 10, depending on the
+dnl version of the POSIX.4a Draft that is implemented.
+dnl 10 == POSIX.4a Final == POSIX.1c-1996 for our purposes.
+dnl 0 implies that the version could not be detected
+dnl or that pthreads.h does exist. Existence of pthreads.h
dnl should be tested separately.
dnl
+dnl tests:
+dnl pthread_yield() was renamed to sched_yield() in Draft 10, so
+dnl only a Draft 10 library will define this
+dnl PTHREAD_INTR_ENABLE was introduced in Draft 6, and renamed to
+dnl PTHREAD_CANCEL_ENABLE in Draft 7. Draft 7-10 has _CANCEL_,
+dnl only Draft 6 has _INTR_
+dnl PTHREAD_MUTEX_INITIALIZER was introduced in Draft 5. It's not
+dnl interesting to us because we don't try to statically
+dnl initialize mutexes. 5-10 has it.
+dnl pthread_attr_create was renamed to pthread_attr_init after Draft 4.
+dnl Draft 6-10 has _init, Draft 4 has _create. (dunno about 5)
+dnl
+dnl Besides the use of sched_yield vs pthread_yield, differences from
+dnl Draft 7 thru Draft 10 don't appear significant for our purposes.
+dnl
AC_DEFUN([OL_POSIX_THREAD_VERSION],
[AC_CACHE_CHECK([POSIX thread version],[ol_cv_pthread_version],[
- AC_EGREP_CPP(pthread_version_final,[
+ AC_EGREP_HEADER(sched_yield,pthread.h,
+ ol_cv_pthread_version=10, [
+
+ AC_EGREP_CPP(draft7,[
# include <pthread.h>
- /* this check could be improved */
-# ifdef PTHREAD_ONCE_INIT
- pthread_version_final;
+# ifdef PTHREAD_CANCEL_ENABLE
+ draft7
# endif
- ], ol_pthread_final=yes, ol_pthread_final=no)
+ ], ol_cv_pthread_version=7, [
- AC_EGREP_CPP(pthread_version_draft4,[
+ AC_EGREP_CPP(draft6,[
# include <pthread.h>
- /* this check could be improved */
-# ifdef pthread_once_init
- pthread_version_draft4;
-# endif
- ], ol_pthread_draft4=yes, ol_pthread_draft4=no)
+#ifdef PTHREAD_INTR_ENABLE
+ draft6
+#endif
+ ], ol_cv_pthread_version=6, [
- if test $ol_pthread_final = yes -a $ol_pthread_draft4 = no; then
- ol_cv_pthread_version=final
- elif test $ol_pthread_final = no -a $ol_pthread_draft4 = yes; then
- ol_cv_pthread_version=draft4
- else
- ol_cv_pthread_version=unknown
- fi
+ AC_EGREP_CPP(draft5,[
+# include <pthread.h>
+#ifdef PTHREAD_MUTEX_INITIALIZER
+ draft5
+#endif
+ ], ol_cv_pthread_version=5, [
+
+ AC_EGREP_HEADER(pthread_attr_create,pthread.h,
+ ol_cv_pthread_version=4, ol_cv_pthread_version=0) ]) ]) ]) ])
])
])dnl
dnl
AC_DEFUN([OL_PTHREAD_TEST_INCLUDES],
[/* pthread test headers */
#include <pthread.h>
+#if HAVE_PTHREADS < 7
+#include <errno.h>
+#endif
#ifndef NULL
#define NULL (void*)0
#endif
])
AC_DEFUN([OL_PTHREAD_TEST_FUNCTION],[
/* pthread test function */
+#ifndef PTHREAD_CREATE_DETACHED
+#define PTHREAD_CREATE_DETACHED 1
+#endif
pthread_t t;
int status;
- int detach = 1;
+ int detach = PTHREAD_CREATE_DETACHED;
-#ifdef HAVE_PTHREADS_FINAL
+#if HAVE_PTHREADS > 4
/* Final pthreads */
pthread_attr_t attr;
status = pthread_attr_init(&attr);
if( status ) return status;
-#if defined( PTHREAD_CREATE_JOINABLE ) || defined( PTHREAD_UNDETACHED )
- if( !detach ) {
-#if defined( PTHREAD_CREATE_JOINABLE )
- status = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+#if HAVE_PTHREADS < 7
+ status = pthread_attr_setdetachstate(&attr, &detach);
+ if( status < 0 ) status = errno;
#else
- status = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_UNDETACHED);
+ status = pthread_attr_setdetachstate(&attr, detach);
#endif
-
-#ifdef PTHREAD_CREATE_DETACHED
- } else {
- status = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-#endif
- }
if( status ) return status;
-#endif
-
status = pthread_create( &t, &attr, task, NULL );
- if( status ) return status;
-
-#if !defined( PTHREAD_CREATE_JOINABLE ) && !defined( PTHREAD_UNDETACHED )
- if( detach ) {
- /* give thread a chance to complete */
- /* it should remain joinable and hence detachable */
- sleep( 1 );
-
- status = pthread_detach( t );
- if( status ) return status;
- }
+#if HAVE_PTHREADS < 7
+ if( status < 0 ) status = errno;
#endif
-
+ if( status ) return status;
#else
/* Draft 4 pthreads */
status = pthread_create( &t, pthread_attr_default, task, NULL );
- if( status ) return status;
+ if( status ) return errno;
- if( detach ) {
- /* give thread a chance to complete */
- /* it should remain joinable and hence detachable */
- sleep( 1 );
+ /* give thread a chance to complete */
+ /* it should remain joinable and hence detachable */
+ sleep( 1 );
- status = pthread_detach( &t );
- if( status ) return status;
- }
+ status = pthread_detach( &t );
+ if( status ) return errno;
#endif
#ifdef HAVE_LINUX_THREADS
AC_DEFINE(HAVE_AIX_SECURITY,1,[define if you have AIX security lib])
])
+dnl ----------------------------------------------------------------
+dnl Check for IBM OS/390
+case "$target" in
+*-ibm-openedition)
+ ac_cv_func_getopt=no
+ AC_DEFINE(BOTH_STRINGS_H,1,[define to use both <string.h> and <strings.h>])
+ ;;
+esac
dnl ----------------------------------------------------------------
dnl Check for module support
if test $ac_cv_header_pthread_h = yes ; then
OL_POSIX_THREAD_VERSION
- if test $ol_cv_pthread_version = final ; then
- AC_DEFINE(HAVE_PTHREADS_FINAL,1,
- [define if pthreads API compatible with final spec])
- elif test $ol_cv_pthread_version = draft4 ; then
- AC_DEFINE(HAVE_PTHREADS_D4,1,
- [define if pthreads API compatible with draft4 spec])
+ if test $ol_cv_pthread_version != 0 ; then
+ AC_DEFINE_UNQUOTED(HAVE_PTHREADS,$ol_cv_pthread_version,
+ [define to pthreads API spec revision])
else
AC_MSG_ERROR([unknown pthread version])
fi
OL_PTHREAD_TRY([-lpthreads],[ol_cv_pthread_lib_lpthreads])
if test $ol_link_threads != no ; then
- AC_DEFINE(HAVE_PTHREADS,1,
- [define if you have POSIX Threads])
-
LTHREAD_LIBS="$LTHREAD_LIBS $ol_link_pthreads"
dnl save flags
#endif
#endif
-#if HAVE_PTHREADS_D4
+#if HAVE_PTHREADS < 6
pthread_create(&t, pthread_attr_default, task, NULL);
#else
pthread_create(&t, NULL, task, NULL);
#include "ldap_pvt_thread.h"
-#if HAVE_PTHREADS_D4
+#if HAVE_PTHREADS == 4
# 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
}
#endif
+/* These are first defined in Draft 7 */
+#ifndef PTHREAD_CREATE_JOINABLE
+#define PTHREAD_CREATE_JOINABLE 0
+#endif
+
+#ifndef PTHREAD_CREATE_DETACHED
+#define PTHREAD_CREATE_DETACHED 1
+#endif
+
int
ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
int detach,
void *arg)
{
int rtn;
-#if defined( HAVE_PTHREADS_FINAL )
pthread_attr_t attr;
+#if HAVE_PTHREADS > 4
pthread_attr_init(&attr);
-
-#if defined( PTHREAD_CREATE_JOINABLE ) || defined( PTHREAD_UNDETACHED )
- if (!detach) {
-#if defined( PTHREAD_CREATE_JOINABLE )
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
#else
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_UNDETACHED);
-#endif
-#ifdef PTHREAD_CREATE_DETACHED
- } else {
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-#elif HAVE_PTHREADS_OS390
- } else {
- int st = __DETACHED;
- pthread_attr_setdetachstate(&attr, &st);
-#endif
- }
+ pthread_attr_create(&attr);
#endif
#if defined(LDAP_PVT_THREAD_STACK_SIZE) && LDAP_PVT_THREAD_STACK_SIZE > 0
pthread_attr_setstacksize( &attr, LDAP_PVT_THREAD_STACK_SIZE );
#endif
- rtn = pthread_create( thread, &attr, start_routine, arg );
-#ifdef HAVE_PTHREADS_OS390
- if ( rtn == -1 ) rtn = errno;
-#endif
-
-#if !defined( PTHREAD_CREATE_JOINABLE ) && !defined( PTHREAD_UNDETACHED )
- if( detach ) {
-#ifdef HAVE_PTHREADS_OS390
- (void) pthread_detach( thread );
+#if HAVE_PTHREADS > 4
+ detach = detach ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE;
+#if HAVE_PTHREADS == 6
+ pthread_attr_setdetachstate(&attr, &detach);
#else
- (void) pthread_detach( *thread );
+ pthread_attr_setdetachstate(&attr, detach);
#endif
- }
#endif
+ rtn = pthread_create( thread, &attr, start_routine, arg );
+#if HAVE_PTHREADS > 4
pthread_attr_destroy(&attr);
-
#else
- rtn = pthread_create( thread, LDAP_INT_THREAD_ATTR_DEFAULT,
- start_routine, arg );
-
+ pthread_attr_delete(&attr);
if( detach ) {
pthread_detach( thread );
}
#endif
+#if HAVE_PTHREADS < 7
+ if ( rtn < 0 ) rtn = errno;
+#endif
return rtn;
}
int
ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
{
-#if !defined( HAVE_PTHREADS_FINAL )
+#if HAVE_PTHREADS < 7
void *dummy;
+
if (thread_return==NULL)
thread_return=&dummy;
-#endif
-#ifdef HAVE_PTHREADS_OS390
- int st = pthread_join( thread, thread_return );
- if ( st == -1 ) st = errno;
- return st;
+
+ if ( pthread_join( thread, thread_return ) < 0 ) return errno;
+ return 0;
#else
return pthread_join( thread, thread_return );
#endif
int
ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
{
-#ifdef HAVE_PTHREAD_KILL
-#ifdef HAVE_PTHREADS_OS390
- int st = pthread_kill( thread, signo );
- if ( st == -1 ) st = errno;
- return st;
-#else
+#if HAVE_PTHREADS > 6
return pthread_kill( thread, signo );
-#endif
+#elif HAVE_PTHREADS == 6
+ if ( pthread_kill( thread, signo ) < 0 ) return errno;
+ return 0;
#else
/* pthread package with DCE */
if (kill( getpid(), signo )<0)
int
ldap_pvt_thread_yield( void )
{
-#ifdef _POSIX_THREAD_IS_GNU_PTH
- sched_yield();
- return 0;
-
-#elif HAVE_SCHED_YIELD
+#if HAVE_PTHREADS == 10
return sched_yield();
-#elif HAVE_PTHREAD_YIELD
-#if HAVE_PTHREADS_OS390
- pthread_yield(NULL);
-#else
- pthread_yield();
-#endif
+#elif defined(_POSIX_THREAD_IS_GNU_PTH)
+ sched_yield();
return 0;
#elif HAVE_THR_YIELD
return thr_yield();
+#elif HAVE_PTHREADS == 6
+ pthread_yield(NULL);
+ return 0;
#else
+ pthread_yield();
return 0;
-#endif
+#endif
}
int
ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT ) < 0 )
+ return errno;
+ return 0;
+#else
return pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT );
+#endif
}
int
ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cond )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_cond_destroy( cond ) < 0 ) return errno;
+ return 0;
+#else
return pthread_cond_destroy( cond );
+#endif
}
int
ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_cond_signal( cond ) < 0 ) return errno;
+ return 0;
+#else
return pthread_cond_signal( cond );
+#endif
}
int
ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_cond_broadcast( cond ) < 0 ) return errno;
+ return 0;
+#else
return pthread_cond_broadcast( cond );
+#endif
}
int
ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond,
ldap_pvt_thread_mutex_t *mutex )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_cond_wait( cond, mutex ) < 0 ) return errno;
+ return 0;
+#else
return pthread_cond_wait( cond, mutex );
+#endif
}
int
ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_mutex_init( mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT )<0)
+ return errno;
+ return 0;
+#else
return pthread_mutex_init( mutex, LDAP_INT_THREAD_MUTEXATTR_DEFAULT );
+#endif
}
int
ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_mutex_destroy( mutex ) < 0 ) return errno;
+ return 0;
+#else
return pthread_mutex_destroy( mutex );
+#endif
}
int
ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_mutex_lock( mutex ) < 0 ) return errno;
+ return 0;
+#else
return pthread_mutex_lock( mutex );
+#endif
}
int
ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_mutex_trylock( mutex ) < 0 ) return errno;
+ return 0;
+#else
return pthread_mutex_trylock( mutex );
+#endif
}
int
ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_mutex_unlock( mutex ) < 0 ) return errno;
+ return 0;
+#else
return pthread_mutex_unlock( mutex );
+#endif
}
#ifdef LDAP_THREAD_HAVE_RDWR
int
ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_rwlock_init( rw, NULL ) < 0 ) return errno;
+ return 0;
+#else
return pthread_rwlock_init( rw, NULL );
+#endif
}
int
ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rw )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_rwlock_destroy( rw ) < 0 ) return errno;
+ return 0;
+#else
return pthread_rwlock_destroy( rw );
+#endif
}
int ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rw )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_rwlock_rdlock( rw ) < 0 ) return errno;
+ return 0;
+#else
return pthread_rwlock_rdlock( rw );
+#endif
}
int ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rw )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_rwlock_tryrdlock( rw ) < 0 ) return errno;
+ return 0;
+#else
return pthread_rwlock_tryrdlock( rw );
+#endif
}
int ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rw )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_rwlock_unlock( rw ) < 0 ) return errno;
+ return 0;
+#else
return pthread_rwlock_unlock( rw );
+#endif
}
int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rw )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_rwlock_wrlock( rw ) < 0 ) return errno;
+ return 0;
+#else
return pthread_rwlock_wrlock( rw );
+#endif
}
int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_rwlock_trywrlock( rw ) < 0 ) return errno;
+ return 0;
+#else
return pthread_rwlock_trywrlock( rw );
+#endif
}
int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
{
+#if HAVE_PTHREADS < 7
+ if ( pthread_rwlock_unlock( rw ) < 0 ) return errno;
+ return 0;
+#else
return pthread_rwlock_unlock( rw );
+#endif
}
#endif /* HAVE_PTHREAD_RDLOCK_DESTROY */