+ol_link_threads=no
+if test $ol_with_threads = auto -o $ol_with_threads = posix ; then
+ AC_CHECK_HEADERS(pthread.h sched.h)
+
+ 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)
+ elif test $ol_cv_pthread_version = draft4 ; then
+ AC_DEFINE(HAVE_PTHREADS_D4)
+ else
+ AC_MSG_ERROR([unknown pthread version])
+ fi
+
+ # consider threads found
+ ol_with_threads=found
+
+ OL_LINUX_THREADS
+
+ if test $ol_cv_linux_threads = yes ; then
+ AC_DEFINE(HAVE_LINUX_THREADS,1)
+ fi
+
+ dnl Now the hard part, how to link
+
+ dnl Check for pthread support in current $LIBS
+ AC_CHECK_FUNC(pthread_create,[ol_link_threads=yes])
+
+ if test $ol_link_threads = no ; then
+ dnl try -pthread
+ AC_CACHE_CHECK([for pthread_create with -pthread],
+ [ol_cv_pthread_flag], [
+ dnl save the flags
+ save_LIBS="$LIBS"
+ LIBS="-pthread $LIBS"
+ AC_TRY_LINK([char pthread();],[
+ pthread_create();
+ ], ol_cv_pthread_flag=yes, ol_cv_pthread_flag=no)
+ dnl restore the LIBS
+ LIBS="$save_LIBS"
+ ])
+
+ if test $ol_cv_pthread_flag = yes ; then
+ LTHREAD_LIBS="$LTHREAD_LIBS -pthread"
+ ol_link_threads=posix
+ fi
+ fi
+
+ if test $ol_link_threads = no ; then
+ dnl try -thread
+ AC_CACHE_CHECK([for pthread_create with -thread],
+ [ol_cv_thread_flag], [
+ dnl save the flags
+ save_LIBS="$LIBS"
+ LIBS="-thread $LIBS"
+ AC_TRY_LINK([char pthread();],[
+ pthread_create();
+ ], ol_cv_thread_flag=yes, ol_cv_thread_flag=no)
+ dnl restore the LIBS
+ LIBS="$save_LIBS"
+ ])
+
+ if test $ol_cv_thread_flag = yes ; then
+ LTHREAD_LIBS="$LTHREAD_LIBS -thread"
+ ol_link_threads=posix
+ fi
+ fi
+
+ if test $ol_link_threads = no ; then
+ dnl try DEC Threads -lpthread -lexc
+ save_LIBS="$LIBS"
+ AC_CHECK_LIB(pthread, pthread_join, [
+ ol_link_threads=posix
+ LTHREAD_LIBS="$LTHREAD_LIBS -lpthread -lexc"
+ if test $ol_with_yielding_select = auto ; then
+ ol_with_yielding_select=yes
+ fi
+ ],,[-lexc])
+ LIBS="$save_LIBS"
+ fi
+
+ if test $ol_link_threads = no ; then
+ dnl try DEC Threads -lpthreads -lmach -lexc -lc_r
+ save_LIBS="$LIBS"
+ AC_CHECK_LIB(pthreads, pthread_join, [
+ ol_link_threads=posix
+ LTHREAD_LIBS="$LTHREAD_LIBS -lpthreads -lmach -lexc -lc_r"
+ if test $ol_with_yielding_select = auto ; then
+ ol_with_yielding_select=yes
+ fi
+ ],,[-lmach -lexc -lc_r])
+ LIBS="$save_LIBS"
+ fi
+
+ if test $ol_link_threads = no ; then
+ dnl try -lpthread
+ save_LIBS="$LIBS"
+ AC_CHECK_LIB(pthread, pthread_create, [
+ ol_link_threads=posix
+ LTHREAD_LIBS="$LTHREAD_LIBS -lpthread"])
+ LIBS="$save_LIBS"
+ fi
+
+ if test $ol_link_threads = no ; then
+ dnl try -lc_r
+ save_LIBS="$LIBS"
+ AC_CHECK_LIB(c_r, pthread_create, [
+ ol_link_threads=posix
+ LTHREAD_LIBS="$LTHREAD_LIBS -lc_r"])
+ LIBS="$save_LIBS"
+ fi
+
+ if test $ol_link_threads != no ; then
+ AC_DEFINE(HAVE_PTHREADS)
+
+ dnl save flags
+ save_CPPFLAGS="$CPPFLAGS"
+ save_LIBS="$LIBS"
+ LIBS="$LTHREAD_LIBS $LIBS"
+
+ dnl All POSIX Thread (final) implementations should have
+ dnl sched_yield instead of pthread yield.
+ dnl check for both
+ AC_CHECK_FUNCS(sched_yield pthread_yield)
+
+ if test $ac_cv_func_sched_yield = no -a \
+ $ac_cv_func_pthread_yield = no ; then
+ dnl Digital UNIX has sched_yield() in -lrt
+ AC_CHECK_LIB(rt, sched_yield,
+ [LTHREAD_LIBS="$LTHREAD_LIBS -lrt"
+ AC_DEFINE(HAVE_SCHED_YIELD,1)
+ ac_cv_func_sched_yield=yes],
+ [ac_cv_func_sched_yield=no])
+ fi
+ if test $ac_cv_func_sched_yield = no -a \
+ $ac_cv_func_pthread_yield = no ; then
+ dnl Solaris has sched_yield() in -lposix4
+ AC_CHECK_LIB(posix4, sched_yield,
+ [LTHREAD_LIBS="$LTHREAD_LIBS -lposix4"
+ AC_DEFINE(HAVE_SCHED_YIELD,1)
+ ac_cv_func_sched_yield=yes],
+ [ac_cv_func_sched_yield=no])
+ fi
+ if test $ac_cv_func_sched_yield = no -a \
+ $ac_cv_func_pthread_yield = no ; then
+ AC_MSG_WARN([could not locate sched_yield() or pthread_yield()])
+ AC_MSG_ERROR([POSIX Threads are not usable])
+ fi
+
+ dnl Check functions for compatibility
+ AC_CHECK_FUNCS(pthread_kill)
+ AC_CHECK_FUNCS( \
+ pthread_attr_create pthread_attr_init \
+ pthread_attr_destroy pthread_attr_delete \
+ pthread_attr_setdetachstate pthread_attr_setdetach_np \
+ )
+
+ dnl Check for setconcurreny functions
+ AC_CHECK_FUNCS( \
+ pthread_setconcurrency \
+ thr_setconcurrency \
+ )
+
+ AC_MSG_CHECKING([if pthread_create() works])
+ AC_CACHE_VAL(ol_cv_pthread_create_works,[
+ AC_TRY_RUN([
+#include <pthread.h>
+#ifndef NULL
+#define NULL (void*)0
+#endif
+
+static void *task(p)
+ void *p;
+{
+ return (void *) (p == NULL);
+}
+
+int main(argc, argv)
+ int argc;
+ char **argv;
+{
+ pthread_t t;
+ exit(pthread_create(&t, NULL, task, NULL));
+}
+],
+ [ol_cv_pthread_create_works=yes],
+ [ol_cv_pthread_create_works=no],
+ [dnl assume yes
+ ol_cv_pthread_create_works=yes])])
+ AC_MSG_RESULT($ol_cv_pthread_create_works)
+
+ if test $ol_cv_pthread_create_works = no ; then
+ AC_MSG_ERROR([pthread.h and pthread_create are not compatible])
+ fi
+
+ dnl Check if select causes an yield
+ if test $ol_with_yielding_select = auto ; then
+ AC_MSG_CHECKING([if select yields when using pthreads])
+ AC_CACHE_VAL(ol_cv_pthread_select_yields,[
+ AC_TRY_RUN([
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <pthread.h>
+#ifndef NULL
+#define NULL (void*) 0
+#endif
+
+static int fildes[2];
+
+static void *task(p)
+ void *p;
+{
+ int i;
+ struct timeval tv;
+
+ fd_set rfds;
+
+ tv.tv_sec=10;
+ tv.tv_usec=0;
+
+ FD_ZERO(&rfds);
+ FD_SET(fildes[0], &rfds);
+
+ /* we're not interested in any fds */
+ i = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
+
+ if(i < 0) {
+ perror("select");
+ exit(0);
+ }
+
+ exit(1); /* if we exit here, the select blocked the whole process */
+}
+
+int main(argc, argv)
+ int argc;
+ char **argv;
+{
+ pthread_t t;
+
+ /* create a pipe to select */
+ if(pipe(&fildes[0])) {
+ perror("select");
+ exit(0);
+ }
+
+#ifdef HAVE_PTHREAD_SETCONCURRENCY
+ (void) pthread_setconcurrency(2);
+#else
+#ifdef HAVE_THR_SETCONCURRENCY
+ /* Set Solaris LWP concurrency to 2 */
+ thr_setconcurrency(2);
+#endif
+#endif
+
+ pthread_create(&t, NULL, task, NULL);
+
+#if HAVE_SCHED_YIELD
+ sched_yield(); /* make sure task runs first */
+#else
+#ifdef HAVE_PTHREAD_YIELD
+ pthread_yield(); /* make sure task runs first */
+#endif
+#endif
+ exit(0);
+}],
+ [ol_cv_pthread_select_yields=yes],
+ [ol_cv_pthread_select_yields=no], [
+ AC_MSG_ERROR([crossing compiling: use --with-yielding_select=yes|no|manual])])])
+ AC_MSG_RESULT($ol_cv_pthread_select_yields)
+
+ if test $ol_cv_pthread_select_yields = yes ; then
+ ol_with_yielding_select=yes
+ fi
+ fi
+
+dnl dnl check for reentrant/threadsafe functions
+dnl AC_CHECK_FUNCS( \
+dnl feof_unlocked \
+dnl unlocked_feof \
+dnl ftrylockfile \
+dnl flockfile \
+dnl putc_unlocked \
+dnl gmtime_r \
+dnl strtok_r \
+dnl )
+
+ dnl restore flags
+ CPPFLAGS="$save_CPPFLAGS"
+ LIBS="$save_LIBS"
+ else
+ AC_MSG_ERROR([could not link with POSIX Threads])
+ fi
+ fi
+
+ if test $ol_with_threads = posix ; then
+ AC_MSG_ERROR([could not locate POSIX Threads])
+ fi