1 dnl OpenLDAP Autoconf thread check
3 dnl This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 dnl Copyright 1998-2010 The OpenLDAP Foundation.
6 dnl All rights reserved.
8 dnl Redistribution and use in source and binary forms, with or without
9 dnl modification, are permitted only as authorized by the OpenLDAP
12 dnl A copy of this license is available in the file LICENSE-OPENLDAP in
13 dnl this directory of the distribution or, alternatively, at
14 dnl <http://www.OpenLDAP.org/license.html>.
16 dnl --------------------------------------------------------------------
18 dnl This file is a fragment of OpenLDAP's build/openldap.m4 and some
19 dnl fragments of OpenLDAP's configure.ac .
21 # OL_THREAD_CHECK([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
23 AC_DEFUN([OL_THREAD_CHECK], [
24 AC_REQUIRE([AC_CANONICAL_HOST])
27 OL_ARG_WITH(threads,[ --with-threads with threads],
28 auto, [auto nt posix mach pth lwp yes no manual] )
30 case "$ol_with_threads$host" in
31 auto*-*-solaris2.[[0-6]])
32 dnl signals sometimes delivered to wrong thread with Solaris 2.6
37 dnl AIX Thread requires we use cc_r or xlc_r.
38 dnl But only do this IF AIX and CC is not set
39 dnl and threads are auto|yes|posix.
41 dnl If we find cc_r|xlc_r, force pthreads and assume
42 dnl pthread_create is in $LIBS (ie: don't bring in
43 dnl any additional thread libraries)
44 dnl If we do not find cc_r|xlc_r, disable threads
48 *-*-aix*) dnl all AIX is not a good idea.
49 if test -z "$CC" ; then
50 case "$ol_with_threads" in
51 auto | yes | posix) ol_aix_threads=yes ;;
57 if test $ol_aix_threads = yes ; then
58 if test -z "${CC}" ; then
59 AC_CHECK_PROGS(CC,cc_r xlc_r cc)
61 if test "$CC" = cc ; then
62 dnl no CC! don't allow --with-threads
63 if test $ol_with_threads != auto ; then
64 AC_MSG_ERROR([--with-threads requires cc_r (or other suitable compiler) on AIX])
66 AC_MSG_WARN([disabling threads, no cc_r on AIX])
72 case ${CC} in cc_r | xlc_r)
74 ol_cv_pthread_create=yes
79 dnl ----------------------------------------------------------------
82 dnl ol_with_yielding_select=${ol_with_yielding_select:-auto}
83 OL_ARG_WITH(yielding_select,[ --with-yielding-select with yielding select],
84 auto, [auto yes no manual] )
86 case $ol_with_threads in auto | yes | nt)
90 if test "$ol_cv_nt_threads" = yes ; then
93 ol_with_yielding_select=yes
95 AC_DEFINE([HAVE_NT_SERVICE_MANAGER], [1], [if you have NT Service Manager])
96 AC_DEFINE([HAVE_NT_EVENT_LOG], [1], [if you have NT Event Log])
99 if test $ol_with_threads = nt ; then
100 AC_MSG_ERROR([could not locate NT Threads])
105 case $ol_with_threads in auto | yes | posix)
107 AC_CHECK_HEADERS(pthread.h)
109 if test $ac_cv_header_pthread_h = yes ; then
110 OL_POSIX_THREAD_VERSION
112 if test $ol_cv_pthread_version != 0 ; then
113 AC_DEFINE_UNQUOTED([HAVE_PTHREADS], [$ol_cv_pthread_version],
114 [define to pthreads API spec revision])
116 AC_MSG_ERROR([unknown pthread version])
119 # consider threads found
120 ol_with_threads=found
122 OL_HEADER_LINUX_THREADS
123 OL_HEADER_GNU_PTH_PTHREAD_H
125 if test $ol_cv_header_gnu_pth_pthread_h = no ; then
126 AC_CHECK_HEADERS(sched.h)
129 dnl Now the hard part, how to link?
131 dnl currently supported checks:
133 dnl Check for no flags
134 dnl pthread_create() in $LIBS
136 dnl Check special pthread (final) flags
137 dnl [skipped] pthread_create() with -mt (Solaris) [disabled]
138 dnl pthread_create() with -kthread (FreeBSD)
139 dnl pthread_create() with -pthread (FreeBSD/Digital Unix)
140 dnl pthread_create() with -pthreads (?)
141 dnl pthread_create() with -mthreads (AIX)
142 dnl pthread_create() with -thread (?)
144 dnl Check pthread (final) libraries
145 dnl pthread_mutex_unlock() in -lpthread -lmach -lexc -lc_r (OSF/1)
146 dnl pthread_mutex_lock() in -lpthread -lmach -lexc (OSF/1)
147 dnl [skipped] pthread_mutex_trylock() in -lpthread -lexc (OSF/1)
148 dnl pthread_join() -Wl,-woff,85 -lpthread (IRIX)
149 dnl pthread_create() in -lpthread (many)
150 dnl pthread_create() in -lc_r (FreeBSD)
152 dnl Check pthread (draft4) flags (depreciated)
153 dnl pthread_create() with -threads (OSF/1)
155 dnl Check pthread (draft4) libraries (depreciated)
156 dnl pthread_mutex_unlock() in -lpthreads -lmach -lexc -lc_r (OSF/1)
157 dnl pthread_mutex_lock() in -lpthreads -lmach -lexc (OSF/1)
158 dnl pthread_mutex_trylock() in -lpthreads -lexc (OSF/1)
159 dnl pthread_create() in -lpthreads (many)
162 dnl pthread_create in $LIBS
163 AC_CACHE_CHECK([for pthread_create in default libraries],
164 ol_cv_pthread_create,[
165 AC_RUN_IFELSE([OL_PTHREAD_TEST_PROGRAM],
166 [ol_cv_pthread_create=yes],
167 [ol_cv_pthread_create=no],
168 [AC_TRY_LINK(OL_PTHREAD_TEST_INCLUDES,OL_PTHREAD_TEST_FUNCTION,
169 [ol_cv_pthread_create=yes],
170 [ol_cv_pthread_create=no])])])
172 if test $ol_cv_pthread_create != no ; then
173 ol_link_threads=posix
177 dnl OL_PTHREAD_TRY([-mt], [ol_cv_pthread_mt])
178 OL_PTHREAD_TRY([-kthread], [ol_cv_pthread_kthread])
179 OL_PTHREAD_TRY([-pthread], [ol_cv_pthread_pthread])
180 OL_PTHREAD_TRY([-pthreads], [ol_cv_pthread_pthreads])
181 OL_PTHREAD_TRY([-mthreads], [ol_cv_pthread_mthreads])
182 OL_PTHREAD_TRY([-thread], [ol_cv_pthread_thread])
184 OL_PTHREAD_TRY([-lpthread -lmach -lexc -lc_r],
185 [ol_cv_pthread_lpthread_lmach_lexc_lc_r])
186 OL_PTHREAD_TRY([-lpthread -lmach -lexc],
187 [ol_cv_pthread_lpthread_lmach_lexc])
188 dnl OL_PTHREAD_TRY([-lpthread -lexc],
189 dnl [ol_cv_pthread_lpthread_lexc])
191 OL_PTHREAD_TRY([-lpthread -Wl,-woff,85],
192 [ol_cv_pthread_lib_lpthread_woff])
194 OL_PTHREAD_TRY([-lpthread], [ol_cv_pthread_lpthread])
195 OL_PTHREAD_TRY([-lc_r], [ol_cv_pthread_lc_r])
197 OL_PTHREAD_TRY([-threads], [ol_cv_pthread_threads])
199 OL_PTHREAD_TRY([-lpthreads -lmach -lexc -lc_r],
200 [ol_cv_pthread_lpthreads_lmach_lexc_lc_r])
201 OL_PTHREAD_TRY([-lpthreads -lmach -lexc],
202 [ol_cv_pthread_lpthreads_lmach_lexc])
203 OL_PTHREAD_TRY([-lpthreads -lexc],
204 [ol_cv_pthread_lpthreads_lexc])
206 OL_PTHREAD_TRY([-lpthreads],[ol_cv_pthread_lib_lpthreads])
208 AC_MSG_NOTICE([ol_link_threads: <$ol_link_threads> ol_link_pthreads <$ol_link_pthreads>])
210 if test $ol_link_threads != no ; then
211 LTHREAD_LIBS="$LTHREAD_LIBS $ol_link_pthreads"
214 save_CPPFLAGS="$CPPFLAGS"
216 LIBS="$LTHREAD_LIBS $LIBS"
218 dnl All POSIX Thread (final) implementations should have
219 dnl sched_yield instead of pthread yield.
220 dnl check for both, and thr_yield for Solaris
221 AC_CHECK_FUNCS(sched_yield pthread_yield thr_yield)
223 if test $ac_cv_func_sched_yield = no &&
224 test $ac_cv_func_pthread_yield = no &&
225 test $ac_cv_func_thr_yield = no ; then
226 dnl Digital UNIX has sched_yield() in -lrt
227 AC_CHECK_LIB(rt, sched_yield,
228 [LTHREAD_LIBS="$LTHREAD_LIBS -lrt"
229 AC_DEFINE([HAVE_SCHED_YIELD], [1],
230 [Define if you have the sched_yield function.])
231 ac_cv_func_sched_yield=yes],
232 [ac_cv_func_sched_yield=no])
234 if test $ac_cv_func_sched_yield = no &&
235 test $ac_cv_func_pthread_yield = no &&
236 test "$ac_cv_func_thr_yield" = no ; then
237 AC_MSG_WARN([could not locate sched_yield() or pthread_yield()])
240 dnl Check functions for compatibility
241 AC_CHECK_FUNCS(pthread_kill)
243 dnl Check for pthread_rwlock_destroy with <pthread.h>
244 dnl as pthread_rwlock_t may not be defined.
245 AC_CACHE_CHECK([for pthread_rwlock_destroy with <pthread.h>],
246 [ol_cv_func_pthread_rwlock_destroy], [
248 AC_LINK_IFELSE([AC_LANG_PROGRAM([[
250 pthread_rwlock_t rwlock;
251 ]], [[pthread_rwlock_destroy(&rwlock);]])],[ol_cv_func_pthread_rwlock_destroy=yes],[ol_cv_func_pthread_rwlock_destroy=no])
253 if test $ol_cv_func_pthread_rwlock_destroy = yes ; then
254 AC_DEFINE([HAVE_PTHREAD_RWLOCK_DESTROY], [1],
255 [define if you have pthread_rwlock_destroy function])
258 dnl Check for pthread_detach with <pthread.h> inclusion
259 dnl as it's symbol may have been mangled.
260 AC_CACHE_CHECK([for pthread_detach with <pthread.h>],
261 [ol_cv_func_pthread_detach], [
263 AC_LINK_IFELSE([AC_LANG_PROGRAM([[
266 #define NULL (void*)0
268 ]], [[pthread_detach(NULL);]])],[ol_cv_func_pthread_detach=yes],[ol_cv_func_pthread_detach=no])
271 if test $ol_cv_func_pthread_detach = no ; then
272 AC_MSG_ERROR([could not locate pthread_detach()])
275 AC_DEFINE([HAVE_PTHREAD_DETACH], [1],
276 [define if you have pthread_detach function])
278 dnl Check for setconcurreny functions
280 pthread_setconcurrency \
281 pthread_getconcurrency \
289 if test $ol_cv_linux_threads = error; then
290 AC_MSG_ERROR([LinuxThreads header/library mismatch]);
293 AC_CACHE_CHECK([if pthread_create() works],
294 ol_cv_pthread_create_works,[
295 AC_RUN_IFELSE([OL_PTHREAD_TEST_PROGRAM],
296 [ol_cv_pthread_create_works=yes],
297 [ol_cv_pthread_create_works=no],
299 ol_cv_pthread_create_works=yes])])
301 if test $ol_cv_pthread_create_works = no ; then
302 AC_MSG_ERROR([pthread_create is not usable, check environment settings])
305 ol_replace_broken_yield=no
308 dnl AC_CHECK_FUNCS(nanosleep)
309 dnl ol_replace_broken_yield=yes
313 if test $ol_replace_broken_yield = yes ; then
314 AC_DEFINE([REPLACE_BROKEN_YIELD], [1],
315 [define if sched_yield yields the entire process])
318 dnl Check if select causes an yield
319 if test x$ol_with_yielding_select = xauto ; then
320 AC_CACHE_CHECK([if select yields when using pthreads],
321 ol_cv_pthread_select_yields,[
322 AC_RUN_IFELSE([AC_LANG_SOURCE([[
323 #include <sys/types.h>
324 #include <sys/time.h>
328 #define NULL (void*) 0
331 static int fildes[2];
345 FD_SET(fildes[0], &rfds);
347 /* we're not interested in any fds */
348 i = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
355 exit(0); /* if we exit here, the select blocked the whole process */
364 /* create a pipe to select */
365 if(pipe(&fildes[0])) {
370 #ifdef HAVE_PTHREAD_SETCONCURRENCY
371 (void) pthread_setconcurrency(2);
373 #ifdef HAVE_THR_SETCONCURRENCY
374 /* Set Solaris LWP concurrency to 2 */
375 thr_setconcurrency(2);
379 #if HAVE_PTHREADS < 6
380 pthread_create(&t, pthread_attr_default, task, NULL);
382 pthread_create(&t, NULL, task, NULL);
385 /* make sure task runs first */
386 #ifdef HAVE_THR_YIELD
388 #elif defined( HAVE_SCHED_YIELD )
390 #elif defined( HAVE_PTHREAD_YIELD )
395 }]])],[ol_cv_pthread_select_yields=no],[ol_cv_pthread_select_yields=yes],[ol_cv_pthread_select_yields=cross])])
397 if test $ol_cv_pthread_select_yields = cross ; then
398 AC_MSG_ERROR([crossing compiling: use --with-yielding-select=yes|no|manual])
401 if test $ol_cv_pthread_select_yields = yes ; then
402 ol_with_yielding_select=yes
407 CPPFLAGS="$save_CPPFLAGS"
410 AC_MSG_ERROR([could not locate usable POSIX Threads])
414 if test $ol_with_threads = posix ; then
415 AC_MSG_ERROR([could not locate POSIX Threads])
420 case $ol_with_threads in auto | yes | mach)
422 dnl check for Mach CThreads
423 AC_CHECK_HEADERS(mach/cthreads.h cthreads.h)
424 if test $ac_cv_header_mach_cthreads_h = yes ; then
425 ol_with_threads=found
427 dnl check for cthreads support in current $LIBS
428 AC_CHECK_FUNC(cthread_fork,[ol_link_threads=yes])
430 if test $ol_link_threads = no ; then
432 dnl this test needs work
433 AC_CACHE_CHECK([for cthread_fork with -all_load],
434 [ol_cv_cthread_all_load], [
437 LIBS="-all_load $LIBS"
438 AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <mach/cthreads.h>]], [[
439 cthread_fork((void *)0, (void *)0);
440 ]])],[ol_cv_cthread_all_load=yes],[ol_cv_cthread_all_load=no])
445 if test $ol_cv_cthread_all_load = yes ; then
446 LTHREAD_LIBS="$LTHREAD_LIBS -all_load"
448 ol_with_threads=found
452 elif test $ac_cv_header_cthreads_h = yes ; then
453 dnl Hurd variant of Mach Cthreads
454 dnl uses <cthreads.h> and -lthreads
456 ol_with_threads=found
460 LIBS="$LIBS -lthreads"
461 AC_CHECK_FUNC(cthread_fork,[ol_link_threads=yes])
464 if test $ol_link_threads = yes ; then
465 LTHREAD_LIBS="-lthreads"
467 ol_with_threads=found
469 AC_MSG_ERROR([could not link with Mach CThreads])
472 elif test $ol_with_threads = mach ; then
473 AC_MSG_ERROR([could not locate Mach CThreads])
476 if test $ol_link_threads = mach ; then
477 AC_DEFINE([HAVE_MACH_CTHREADS], [1],
478 [define if you have Mach Cthreads])
479 elif test $ol_with_threads = found ; then
480 AC_MSG_ERROR([could not link with Mach CThreads])
485 case $ol_with_threads in auto | yes | pth)
487 AC_CHECK_HEADERS(pth.h)
489 if test $ac_cv_header_pth_h = yes ; then
490 AC_CHECK_LIB(pth, pth_version, [have_pth=yes], [have_pth=no])
492 if test $have_pth = yes ; then
493 AC_DEFINE([HAVE_GNU_PTH], [1], [if you have GNU Pth])
494 LTHREAD_LIBS="$LTHREAD_LIBS -lpth"
496 ol_with_threads=found
498 if test x$ol_with_yielding_select = xauto ; then
499 ol_with_yielding_select=yes
506 case $ol_with_threads in auto | yes | lwp)
508 dnl check for SunOS5 LWP
509 AC_CHECK_HEADERS(thread.h synch.h)
510 if test $ac_cv_header_thread_h = yes &&
511 test $ac_cv_header_synch_h = yes ; then
512 AC_CHECK_LIB(thread, thr_create, [have_thr=yes], [have_thr=no])
514 if test $have_thr = yes ; then
515 AC_DEFINE([HAVE_THR], [1],
516 [if you have Solaris LWP (thr) package])
517 LTHREAD_LIBS="$LTHREAD_LIBS -lthread"
520 if test x$ol_with_yielding_select = xauto ; then
521 ol_with_yielding_select=yes
524 dnl Check for setconcurrency functions
532 dnl check for SunOS4 LWP
533 AC_CHECK_HEADERS(lwp/lwp.h)
534 if test $ac_cv_header_lwp_lwp_h = yes ; then
535 AC_CHECK_LIB(lwp, lwp_create, [have_lwp=yes], [have_lwp=no])
537 if test $have_lwp = yes ; then
538 AC_DEFINE([HAVE_LWP], [1],
539 [if you have SunOS LWP package])
540 LTHREAD_LIBS="$LTHREAD_LIBS -llwp"
543 if test x$ol_with_yielding_select = xauto ; then
544 ol_with_yielding_select=no
551 if test $ol_with_yielding_select = yes ; then
552 AC_DEFINE([HAVE_YIELDING_SELECT], [1],
553 [define if select implicitly yields])
556 if test $ol_with_threads = manual ; then
557 dnl User thinks he can manually configure threads.
560 AC_MSG_WARN([thread defines and link options must be set manually])
562 AC_CHECK_HEADERS(pthread.h sched.h)
563 AC_CHECK_FUNCS(sched_yield pthread_yield)
564 OL_HEADER_LINUX_THREADS
566 AC_CHECK_HEADERS(mach/cthreads.h)
567 AC_CHECK_HEADERS(lwp/lwp.h)
568 AC_CHECK_HEADERS(thread.h synch.h)
571 if test $ol_link_threads != no && test $ol_link_threads != nt ; then
572 dnl needed to get reentrant/threadsafe versions
574 AC_DEFINE([REENTRANT], [1], [enable thread safety])
575 AC_DEFINE([_REENTRANT], [1], [enable thread safety])
576 AC_DEFINE([THREAD_SAFE], [1], [enable thread safety])
577 AC_DEFINE([_THREAD_SAFE], [1], [enable thread safety])
578 AC_DEFINE([THREADSAFE], [1], [enable thread safety])
579 AC_DEFINE([_THREADSAFE], [1], [enable thread safety])
580 AC_DEFINE([_SGI_MP_SOURCE], [1], [enable thread safety])
582 dnl The errno declaration may dependent upon _REENTRANT.
583 dnl If it does, we must link with thread support.
584 AC_CACHE_CHECK([for thread specific errno],
585 [ol_cv_errno_thread_specific], [
586 AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <errno.h>]], [[errno = 0;]])],[ol_cv_errno_thread_specific=yes],[ol_cv_errno_thread_specific=no])
589 dnl The h_errno declaration may dependent upon _REENTRANT.
590 dnl If it does, we must link with thread support.
591 AC_CACHE_CHECK([for thread specific h_errno],
592 [ol_cv_h_errno_thread_specific], [
593 AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <netdb.h>]], [[h_errno = 0;]])],[ol_cv_h_errno_thread_specific=yes],[ol_cv_h_errno_thread_specific=no])
596 if test $ol_cv_errno_thread_specific != yes ||
597 test $ol_cv_h_errno_thread_specific != yes ; then
598 LIBS="$LTHREAD_LIBS $LIBS"
602 dnl When in thread environment, use
603 dnl #if defined( HAVE_REENTRANT_FUNCTIONS ) || defined( HAVE_FUNC_R )
606 dnl # if defined( HAVE_THREADS )
610 dnl # if defined( HAVE_THREADS )
615 dnl HAVE_REENTRANT_FUNCTIONS is derived from:
616 dnl _POSIX_REENTRANT_FUNCTIONS
617 dnl _POSIX_THREAD_SAFE_FUNCTIONS
618 dnl _POSIX_THREADSAFE_FUNCTIONS
620 dnl and is currently defined in <ldap_pvt_thread.h>
622 dnl HAVE_THREADS is defined by <ldap_pvt_thread.h> iff -UNO_THREADS
624 dnl libldap/*.c should only include <ldap_pvt_thread.h> iff
625 dnl LDAP_R_COMPILE is defined. ie:
626 dnl #ifdef LDAP_R_COMPILE
627 dnl # include <ldap_pvt_thread.h>
630 dnl LDAP_R_COMPILE is defined by libldap_r/Makefile.in
631 dnl specifically for compiling the threadsafe version of
632 dnl the ldap library (-lldap_r).
634 dnl dnl check for reentrant/threadsafe functions
636 dnl dnl note: these should only be used when linking
637 dnl dnl with $LTHREAD_LIBS
639 dnl save_CPPFLAGS="$CPPFLAGS"
640 dnl save_LIBS="$LIBS"
641 dnl LIBS="$LTHREAD_LIBS $LIBS"
642 dnl AC_CHECK_FUNCS( \
644 dnl gethostbyaddr_r gethostbyname_r \
645 dnl feof_unlocked unlocked_feof \
646 dnl putc_unlocked unlocked_putc \
647 dnl flockfile ftrylockfile \
649 dnl CPPFLAGS="$save_CPPFLAGS"
650 dnl LIBS="$save_LIBS"
653 if test $ol_link_threads = no ; then
654 if test $ol_with_threads = yes ; then
655 AC_MSG_ERROR([no suitable thread support])
658 if test $ol_with_threads = auto ; then
659 AC_MSG_WARN([no suitable thread support, disabling threads])
663 AC_DEFINE([NO_THREADS], [1],
664 [define if you have (or want) no threads])
671 if test $ol_link_threads != no ; then
672 AC_DEFINE([LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE], [1],
673 [define to 1 if library is thread safe])
676 # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
677 case "$ol_with_threads" in
683 ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
689 AC_SUBST(BUILD_THREAD)
690 AC_SUBST(LTHREAD_LIBS)