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 # OL_THREAD_CHECK([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
20 AC_DEFUN([OL_THREAD_CHECK], [
21 AC_REQUIRE([AC_CANONICAL_HOST])
24 OL_ARG_WITH(threads,[ --with-threads with threads],
25 auto, [auto nt posix mach pth lwp yes no manual] )
27 case "$ol_with_threads$host" in
28 auto*-*-solaris2.[[0-6]])
29 dnl signals sometimes delivered to wrong thread with Solaris 2.6
34 dnl AIX Thread requires we use cc_r or xlc_r.
35 dnl But only do this IF AIX and CC is not set
36 dnl and threads are auto|yes|posix.
38 dnl If we find cc_r|xlc_r, force pthreads and assume
39 dnl pthread_create is in $LIBS (ie: don't bring in
40 dnl any additional thread libraries)
41 dnl If we do not find cc_r|xlc_r, disable threads
45 *-*-aix*) dnl all AIX is not a good idea.
46 if test -z "$CC" ; then
47 case "$ol_with_threads" in
48 auto | yes | posix) ol_aix_threads=yes ;;
54 if test $ol_aix_threads = yes ; then
55 if test -z "${CC}" ; then
56 AC_CHECK_PROGS(CC,cc_r xlc_r cc)
58 if test "$CC" = cc ; then
59 dnl no CC! don't allow --with-threads
60 if test $ol_with_threads != auto ; then
61 AC_MSG_ERROR([--with-threads requires cc_r (or other suitable compiler) on AIX])
63 AC_MSG_WARN([disabling threads, no cc_r on AIX])
69 case ${CC} in cc_r | xlc_r)
71 ol_cv_pthread_create=yes
76 dnl ----------------------------------------------------------------
79 dnl ol_with_yielding_select=${ol_with_yielding_select:-auto}
80 OL_ARG_WITH(yielding_select,[ --with-yielding-select with yielding select],
81 auto, [auto yes no manual] )
83 case $ol_with_threads in auto | yes | nt)
87 if test "$ol_cv_nt_threads" = yes ; then
90 ol_with_yielding_select=yes
92 AC_DEFINE([HAVE_NT_SERVICE_MANAGER], [1], [if you have NT Service Manager])
93 AC_DEFINE([HAVE_NT_EVENT_LOG], [1], [if you have NT Event Log])
96 if test $ol_with_threads = nt ; then
97 AC_MSG_ERROR([could not locate NT Threads])
102 case $ol_with_threads in auto | yes | posix)
104 AC_CHECK_HEADERS(pthread.h)
106 if test $ac_cv_header_pthread_h = yes ; then
107 OL_POSIX_THREAD_VERSION
109 if test $ol_cv_pthread_version != 0 ; then
110 AC_DEFINE_UNQUOTED([HAVE_PTHREADS], [$ol_cv_pthread_version],
111 [define to pthreads API spec revision])
113 AC_MSG_ERROR([unknown pthread version])
116 # consider threads found
117 ol_with_threads=found
119 OL_HEADER_LINUX_THREADS
120 OL_HEADER_GNU_PTH_PTHREAD_H
122 if test $ol_cv_header_gnu_pth_pthread_h = no ; then
123 AC_CHECK_HEADERS(sched.h)
126 dnl Now the hard part, how to link?
128 dnl currently supported checks:
130 dnl Check for no flags
131 dnl pthread_create() in $LIBS
133 dnl Check special pthread (final) flags
134 dnl [skipped] pthread_create() with -mt (Solaris) [disabled]
135 dnl pthread_create() with -kthread (FreeBSD)
136 dnl pthread_create() with -pthread (FreeBSD/Digital Unix)
137 dnl pthread_create() with -pthreads (?)
138 dnl pthread_create() with -mthreads (AIX)
139 dnl pthread_create() with -thread (?)
141 dnl Check pthread (final) libraries
142 dnl pthread_mutex_unlock() in -lpthread -lmach -lexc -lc_r (OSF/1)
143 dnl pthread_mutex_lock() in -lpthread -lmach -lexc (OSF/1)
144 dnl [skipped] pthread_mutex_trylock() in -lpthread -lexc (OSF/1)
145 dnl pthread_join() -Wl,-woff,85 -lpthread (IRIX)
146 dnl pthread_create() in -lpthread (many)
147 dnl pthread_create() in -lc_r (FreeBSD)
149 dnl Check pthread (draft4) flags (depreciated)
150 dnl pthread_create() with -threads (OSF/1)
152 dnl Check pthread (draft4) libraries (depreciated)
153 dnl pthread_mutex_unlock() in -lpthreads -lmach -lexc -lc_r (OSF/1)
154 dnl pthread_mutex_lock() in -lpthreads -lmach -lexc (OSF/1)
155 dnl pthread_mutex_trylock() in -lpthreads -lexc (OSF/1)
156 dnl pthread_create() in -lpthreads (many)
159 dnl pthread_create in $LIBS
160 AC_CACHE_CHECK([for pthread_create in default libraries],
161 ol_cv_pthread_create,[
162 AC_RUN_IFELSE([OL_PTHREAD_TEST_PROGRAM],
163 [ol_cv_pthread_create=yes],
164 [ol_cv_pthread_create=no],
165 [AC_TRY_LINK(OL_PTHREAD_TEST_INCLUDES,OL_PTHREAD_TEST_FUNCTION,
166 [ol_cv_pthread_create=yes],
167 [ol_cv_pthread_create=no])])])
169 if test $ol_cv_pthread_create != no ; then
170 ol_link_threads=posix
174 dnl OL_PTHREAD_TRY([-mt], [ol_cv_pthread_mt])
175 OL_PTHREAD_TRY([-kthread], [ol_cv_pthread_kthread])
176 OL_PTHREAD_TRY([-pthread], [ol_cv_pthread_pthread])
177 OL_PTHREAD_TRY([-pthreads], [ol_cv_pthread_pthreads])
178 OL_PTHREAD_TRY([-mthreads], [ol_cv_pthread_mthreads])
179 OL_PTHREAD_TRY([-thread], [ol_cv_pthread_thread])
181 OL_PTHREAD_TRY([-lpthread -lmach -lexc -lc_r],
182 [ol_cv_pthread_lpthread_lmach_lexc_lc_r])
183 OL_PTHREAD_TRY([-lpthread -lmach -lexc],
184 [ol_cv_pthread_lpthread_lmach_lexc])
185 dnl OL_PTHREAD_TRY([-lpthread -lexc],
186 dnl [ol_cv_pthread_lpthread_lexc])
188 OL_PTHREAD_TRY([-lpthread -Wl,-woff,85],
189 [ol_cv_pthread_lib_lpthread_woff])
191 OL_PTHREAD_TRY([-lpthread], [ol_cv_pthread_lpthread])
192 OL_PTHREAD_TRY([-lc_r], [ol_cv_pthread_lc_r])
194 OL_PTHREAD_TRY([-threads], [ol_cv_pthread_threads])
196 OL_PTHREAD_TRY([-lpthreads -lmach -lexc -lc_r],
197 [ol_cv_pthread_lpthreads_lmach_lexc_lc_r])
198 OL_PTHREAD_TRY([-lpthreads -lmach -lexc],
199 [ol_cv_pthread_lpthreads_lmach_lexc])
200 OL_PTHREAD_TRY([-lpthreads -lexc],
201 [ol_cv_pthread_lpthreads_lexc])
203 OL_PTHREAD_TRY([-lpthreads],[ol_cv_pthread_lib_lpthreads])
205 if test $ol_link_threads != no ; then
206 LTHREAD_LIBS="$LTHREAD_LIBS $ol_link_pthreads"
209 save_CPPFLAGS="$CPPFLAGS"
211 LIBS="$LTHREAD_LIBS $LIBS"
213 dnl All POSIX Thread (final) implementations should have
214 dnl sched_yield instead of pthread yield.
215 dnl check for both, and thr_yield for Solaris
216 AC_CHECK_FUNCS(sched_yield pthread_yield thr_yield)
218 if test $ac_cv_func_sched_yield = no &&
219 test $ac_cv_func_pthread_yield = no &&
220 test $ac_cv_func_thr_yield = no ; then
221 dnl Digital UNIX has sched_yield() in -lrt
222 AC_CHECK_LIB(rt, sched_yield,
223 [LTHREAD_LIBS="$LTHREAD_LIBS -lrt"
224 AC_DEFINE([HAVE_SCHED_YIELD], [1],
225 [Define if you have the sched_yield function.])
226 ac_cv_func_sched_yield=yes],
227 [ac_cv_func_sched_yield=no])
229 if test $ac_cv_func_sched_yield = no &&
230 test $ac_cv_func_pthread_yield = no &&
231 test "$ac_cv_func_thr_yield" = no ; then
232 AC_MSG_WARN([could not locate sched_yield() or pthread_yield()])
235 dnl Check functions for compatibility
236 AC_CHECK_FUNCS(pthread_kill)
238 dnl Check for pthread_rwlock_destroy with <pthread.h>
239 dnl as pthread_rwlock_t may not be defined.
240 AC_CACHE_CHECK([for pthread_rwlock_destroy with <pthread.h>],
241 [ol_cv_func_pthread_rwlock_destroy], [
243 AC_LINK_IFELSE([AC_LANG_PROGRAM([[
245 pthread_rwlock_t rwlock;
246 ]], [[pthread_rwlock_destroy(&rwlock);]])],[ol_cv_func_pthread_rwlock_destroy=yes],[ol_cv_func_pthread_rwlock_destroy=no])
248 if test $ol_cv_func_pthread_rwlock_destroy = yes ; then
249 AC_DEFINE([HAVE_PTHREAD_RWLOCK_DESTROY], [1],
250 [define if you have pthread_rwlock_destroy function])
253 dnl Check for pthread_detach with <pthread.h> inclusion
254 dnl as it's symbol may have been mangled.
255 AC_CACHE_CHECK([for pthread_detach with <pthread.h>],
256 [ol_cv_func_pthread_detach], [
258 AC_LINK_IFELSE([AC_LANG_PROGRAM([[
261 #define NULL (void*)0
263 ]], [[pthread_detach(NULL);]])],[ol_cv_func_pthread_detach=yes],[ol_cv_func_pthread_detach=no])
266 if test $ol_cv_func_pthread_detach = no ; then
267 AC_MSG_ERROR([could not locate pthread_detach()])
270 AC_DEFINE([HAVE_PTHREAD_DETACH], [1],
271 [define if you have pthread_detach function])
273 dnl Check for setconcurreny functions
275 pthread_setconcurrency \
276 pthread_getconcurrency \
284 if test $ol_cv_linux_threads = error; then
285 AC_MSG_ERROR([LinuxThreads header/library mismatch]);
288 AC_CACHE_CHECK([if pthread_create() works],
289 ol_cv_pthread_create_works,[
290 AC_RUN_IFELSE([OL_PTHREAD_TEST_PROGRAM],
291 [ol_cv_pthread_create_works=yes],
292 [ol_cv_pthread_create_works=no],
294 ol_cv_pthread_create_works=yes])])
296 if test $ol_cv_pthread_create_works = no ; then
297 AC_MSG_ERROR([pthread_create is not usable, check environment settings])
300 ol_replace_broken_yield=no
303 dnl AC_CHECK_FUNCS(nanosleep)
304 dnl ol_replace_broken_yield=yes
308 if test $ol_replace_broken_yield = yes ; then
309 AC_DEFINE([REPLACE_BROKEN_YIELD], [1],
310 [define if sched_yield yields the entire process])
313 dnl Check if select causes an yield
314 if test x$ol_with_yielding_select = xauto ; then
315 AC_CACHE_CHECK([if select yields when using pthreads],
316 ol_cv_pthread_select_yields,[
317 AC_RUN_IFELSE([AC_LANG_SOURCE([[
318 #include <sys/types.h>
319 #include <sys/time.h>
323 #define NULL (void*) 0
326 static int fildes[2];
340 FD_SET(fildes[0], &rfds);
342 /* we're not interested in any fds */
343 i = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
350 exit(0); /* if we exit here, the select blocked the whole process */
359 /* create a pipe to select */
360 if(pipe(&fildes[0])) {
365 #ifdef HAVE_PTHREAD_SETCONCURRENCY
366 (void) pthread_setconcurrency(2);
368 #ifdef HAVE_THR_SETCONCURRENCY
369 /* Set Solaris LWP concurrency to 2 */
370 thr_setconcurrency(2);
374 #if HAVE_PTHREADS < 6
375 pthread_create(&t, pthread_attr_default, task, NULL);
377 pthread_create(&t, NULL, task, NULL);
380 /* make sure task runs first */
381 #ifdef HAVE_THR_YIELD
383 #elif defined( HAVE_SCHED_YIELD )
385 #elif defined( HAVE_PTHREAD_YIELD )
390 }]])],[ol_cv_pthread_select_yields=no],[ol_cv_pthread_select_yields=yes],[ol_cv_pthread_select_yields=cross])])
392 if test $ol_cv_pthread_select_yields = cross ; then
393 AC_MSG_ERROR([crossing compiling: use --with-yielding-select=yes|no|manual])
396 if test $ol_cv_pthread_select_yields = yes ; then
397 ol_with_yielding_select=yes
402 CPPFLAGS="$save_CPPFLAGS"
405 AC_MSG_ERROR([could not locate usable POSIX Threads])
409 if test $ol_with_threads = posix ; then
410 AC_MSG_ERROR([could not locate POSIX Threads])
415 case $ol_with_threads in auto | yes | mach)
417 dnl check for Mach CThreads
418 AC_CHECK_HEADERS(mach/cthreads.h cthreads.h)
419 if test $ac_cv_header_mach_cthreads_h = yes ; then
420 ol_with_threads=found
422 dnl check for cthreads support in current $LIBS
423 AC_CHECK_FUNC(cthread_fork,[ol_link_threads=yes])
425 if test $ol_link_threads = no ; then
427 dnl this test needs work
428 AC_CACHE_CHECK([for cthread_fork with -all_load],
429 [ol_cv_cthread_all_load], [
432 LIBS="-all_load $LIBS"
433 AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <mach/cthreads.h>]], [[
434 cthread_fork((void *)0, (void *)0);
435 ]])],[ol_cv_cthread_all_load=yes],[ol_cv_cthread_all_load=no])
440 if test $ol_cv_cthread_all_load = yes ; then
441 LTHREAD_LIBS="$LTHREAD_LIBS -all_load"
443 ol_with_threads=found
447 elif test $ac_cv_header_cthreads_h = yes ; then
448 dnl Hurd variant of Mach Cthreads
449 dnl uses <cthreads.h> and -lthreads
451 ol_with_threads=found
455 LIBS="$LIBS -lthreads"
456 AC_CHECK_FUNC(cthread_fork,[ol_link_threads=yes])
459 if test $ol_link_threads = yes ; then
460 LTHREAD_LIBS="-lthreads"
462 ol_with_threads=found
464 AC_MSG_ERROR([could not link with Mach CThreads])
467 elif test $ol_with_threads = mach ; then
468 AC_MSG_ERROR([could not locate Mach CThreads])
471 if test $ol_link_threads = mach ; then
472 AC_DEFINE([HAVE_MACH_CTHREADS], [1],
473 [define if you have Mach Cthreads])
474 elif test $ol_with_threads = found ; then
475 AC_MSG_ERROR([could not link with Mach CThreads])
480 case $ol_with_threads in auto | yes | pth)
482 AC_CHECK_HEADERS(pth.h)
484 if test $ac_cv_header_pth_h = yes ; then
485 AC_CHECK_LIB(pth, pth_version, [have_pth=yes], [have_pth=no])
487 if test $have_pth = yes ; then
488 AC_DEFINE([HAVE_GNU_PTH], [1], [if you have GNU Pth])
489 LTHREAD_LIBS="$LTHREAD_LIBS -lpth"
491 ol_with_threads=found
493 if test x$ol_with_yielding_select = xauto ; then
494 ol_with_yielding_select=yes
501 case $ol_with_threads in auto | yes | lwp)
503 dnl check for SunOS5 LWP
504 AC_CHECK_HEADERS(thread.h synch.h)
505 if test $ac_cv_header_thread_h = yes &&
506 test $ac_cv_header_synch_h = yes ; then
507 AC_CHECK_LIB(thread, thr_create, [have_thr=yes], [have_thr=no])
509 if test $have_thr = yes ; then
510 AC_DEFINE([HAVE_THR], [1],
511 [if you have Solaris LWP (thr) package])
512 LTHREAD_LIBS="$LTHREAD_LIBS -lthread"
515 if test x$ol_with_yielding_select = xauto ; then
516 ol_with_yielding_select=yes
519 dnl Check for setconcurrency functions
527 dnl check for SunOS4 LWP
528 AC_CHECK_HEADERS(lwp/lwp.h)
529 if test $ac_cv_header_lwp_lwp_h = yes ; then
530 AC_CHECK_LIB(lwp, lwp_create, [have_lwp=yes], [have_lwp=no])
532 if test $have_lwp = yes ; then
533 AC_DEFINE([HAVE_LWP], [1],
534 [if you have SunOS LWP package])
535 LTHREAD_LIBS="$LTHREAD_LIBS -llwp"
538 if test x$ol_with_yielding_select = xauto ; then
539 ol_with_yielding_select=no
546 if test $ol_with_yielding_select = yes ; then
547 AC_DEFINE([HAVE_YIELDING_SELECT], [1],
548 [define if select implicitly yields])
551 if test $ol_with_threads = manual ; then
552 dnl User thinks he can manually configure threads.
555 AC_MSG_WARN([thread defines and link options must be set manually])
557 AC_CHECK_HEADERS(pthread.h sched.h)
558 AC_CHECK_FUNCS(sched_yield pthread_yield)
559 OL_HEADER_LINUX_THREADS
561 AC_CHECK_HEADERS(mach/cthreads.h)
562 AC_CHECK_HEADERS(lwp/lwp.h)
563 AC_CHECK_HEADERS(thread.h synch.h)
566 if test $ol_link_threads != no && test $ol_link_threads != nt ; then
567 dnl needed to get reentrant/threadsafe versions
569 AC_DEFINE([REENTRANT], [1], [enable thread safety])
570 AC_DEFINE([_REENTRANT], [1], [enable thread safety])
571 AC_DEFINE([THREAD_SAFE], [1], [enable thread safety])
572 AC_DEFINE([_THREAD_SAFE], [1], [enable thread safety])
573 AC_DEFINE([THREADSAFE], [1], [enable thread safety])
574 AC_DEFINE([_THREADSAFE], [1], [enable thread safety])
575 AC_DEFINE([_SGI_MP_SOURCE], [1], [enable thread safety])
577 dnl The errno declaration may dependent upon _REENTRANT.
578 dnl If it does, we must link with thread support.
579 AC_CACHE_CHECK([for thread specific errno],
580 [ol_cv_errno_thread_specific], [
581 AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <errno.h>]], [[errno = 0;]])],[ol_cv_errno_thread_specific=yes],[ol_cv_errno_thread_specific=no])
584 dnl The h_errno declaration may dependent upon _REENTRANT.
585 dnl If it does, we must link with thread support.
586 AC_CACHE_CHECK([for thread specific h_errno],
587 [ol_cv_h_errno_thread_specific], [
588 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])
591 if test $ol_cv_errno_thread_specific != yes ||
592 test $ol_cv_h_errno_thread_specific != yes ; then
593 LIBS="$LTHREAD_LIBS $LIBS"
597 dnl When in thread environment, use
598 dnl #if defined( HAVE_REENTRANT_FUNCTIONS ) || defined( HAVE_FUNC_R )
601 dnl # if defined( HAVE_THREADS )
605 dnl # if defined( HAVE_THREADS )
610 dnl HAVE_REENTRANT_FUNCTIONS is derived from:
611 dnl _POSIX_REENTRANT_FUNCTIONS
612 dnl _POSIX_THREAD_SAFE_FUNCTIONS
613 dnl _POSIX_THREADSAFE_FUNCTIONS
615 dnl and is currently defined in <ldap_pvt_thread.h>
617 dnl HAVE_THREADS is defined by <ldap_pvt_thread.h> iff -UNO_THREADS
619 dnl libldap/*.c should only include <ldap_pvt_thread.h> iff
620 dnl LDAP_R_COMPILE is defined. ie:
621 dnl #ifdef LDAP_R_COMPILE
622 dnl # include <ldap_pvt_thread.h>
625 dnl LDAP_R_COMPILE is defined by libldap_r/Makefile.in
626 dnl specifically for compiling the threadsafe version of
627 dnl the ldap library (-lldap_r).
629 dnl dnl check for reentrant/threadsafe functions
631 dnl dnl note: these should only be used when linking
632 dnl dnl with $LTHREAD_LIBS
634 dnl save_CPPFLAGS="$CPPFLAGS"
635 dnl save_LIBS="$LIBS"
636 dnl LIBS="$LTHREAD_LIBS $LIBS"
637 dnl AC_CHECK_FUNCS( \
639 dnl gethostbyaddr_r gethostbyname_r \
640 dnl feof_unlocked unlocked_feof \
641 dnl putc_unlocked unlocked_putc \
642 dnl flockfile ftrylockfile \
644 dnl CPPFLAGS="$save_CPPFLAGS"
645 dnl LIBS="$save_LIBS"
648 if test $ol_link_threads = no ; then
649 if test $ol_with_threads = yes ; then
650 AC_MSG_ERROR([no suitable thread support])
653 if test $ol_with_threads = auto ; then
654 AC_MSG_WARN([no suitable thread support, disabling threads])
658 AC_DEFINE([NO_THREADS], [1],
659 [define if you have (or want) no threads])
666 if test $ol_link_threads != no ; then
667 AC_DEFINE([LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE], [1],
668 [define to 1 if library is thread safe])
671 # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
672 case "$ol_with_threads" in
678 ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])