1# lock.m4 serial 6 (gettext-0.16)
2dnl Copyright (C) 2005-2006 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7dnl From Bruno Haible.
8
9dnl Tests for a multithreading library to be used.
10dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS,
11dnl USE_PTH_THREADS, USE_WIN32_THREADS
12dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use
13dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with
14dnl libtool).
15dnl Sets the variables LIBMULTITHREAD and LTLIBMULTITHREAD similarly, for
16dnl programs that really need multithread functionality. The difference
17dnl between LIBTHREAD and LIBMULTITHREAD is that on platforms supporting weak
18dnl symbols, typically LIBTHREAD="" whereas LIBMULTITHREAD="-lpthread".
19dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for
20dnl multithread-safe programs.
21
22AC_DEFUN([gl_LOCK_EARLY],
23[
24  AC_REQUIRE([gl_LOCK_EARLY_BODY])
25])
26
27dnl The guts of gl_LOCK_EARLY. Needs to be expanded only once.
28
29AC_DEFUN([gl_LOCK_EARLY_BODY],
30[
31  dnl Ordering constraints: This macro modifies CPPFLAGS in a way that
32  dnl influences the result of the autoconf tests that test for *_unlocked
33  dnl declarations, on AIX 5 at least. Therefore it must come early.
34  AC_BEFORE([$0], [gl_FUNC_GLIBC_UNLOCKED_IO])dnl
35  AC_BEFORE([$0], [gl_ARGP])dnl
36
37  AC_REQUIRE([AC_CANONICAL_HOST])
38  AC_REQUIRE([AC_GNU_SOURCE]) dnl needed for pthread_rwlock_t on glibc systems
39  dnl Check for multithreading.
40  AC_ARG_ENABLE(threads,
41AC_HELP_STRING([--enable-threads={posix|solaris|pth|win32}], [specify multithreading API])
42AC_HELP_STRING([--disable-threads], [build without multithread safety]),
43    [gl_use_threads=$enableval],
44    [case "$host_os" in
45       dnl Disable multithreading by default on OSF/1, because it interferes
46       dnl with fork()/exec(): When msgexec is linked with -lpthread, its child
47       dnl process gets an endless segmentation fault inside execvp().
48       osf*) gl_use_threads=no ;;
49       *)    gl_use_threads=yes ;;
50     esac
51    ])
52  if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
53    # For using <pthread.h>:
54    case "$host_os" in
55      osf*)
56        # On OSF/1, the compiler needs the flag -D_REENTRANT so that it
57        # groks <pthread.h>. cc also understands the flag -pthread, but
58        # we don't use it because 1. gcc-2.95 doesn't understand -pthread,
59        # 2. putting a flag into CPPFLAGS that has an effect on the linker
60        # causes the AC_TRY_LINK test below to succeed unexpectedly,
61        # leading to wrong values of LIBTHREAD and LTLIBTHREAD.
62        CPPFLAGS="$CPPFLAGS -D_REENTRANT"
63        ;;
64    esac
65    # Some systems optimize for single-threaded programs by default, and
66    # need special flags to disable these optimizations. For example, the
67    # definition of 'errno' in <errno.h>.
68    case "$host_os" in
69      aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;;
70      solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;;
71    esac
72  fi
73])
74
75dnl The guts of gl_LOCK. Needs to be expanded only once.
76
77AC_DEFUN([gl_LOCK_BODY],
78[
79  AC_REQUIRE([gl_LOCK_EARLY_BODY])
80  gl_threads_api=none
81  LIBTHREAD=
82  LTLIBTHREAD=
83  LIBMULTITHREAD=
84  LTLIBMULTITHREAD=
85  if test "$gl_use_threads" != no; then
86    dnl Check whether the compiler and linker support weak declarations.
87    AC_MSG_CHECKING([whether imported symbols can be declared weak])
88    gl_have_weak=no
89    AC_TRY_LINK([extern void xyzzy ();
90#pragma weak xyzzy], [xyzzy();], [gl_have_weak=yes])
91    AC_MSG_RESULT([$gl_have_weak])
92    if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
93      # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that
94      # it groks <pthread.h>. It's added above, in gl_LOCK_EARLY_BODY.
95      AC_CHECK_HEADER(pthread.h, gl_have_pthread_h=yes, gl_have_pthread_h=no)
96      if test "$gl_have_pthread_h" = yes; then
97        # Other possible tests:
98        #   -lpthreads (FSU threads, PCthreads)
99        #   -lgthreads
100        gl_have_pthread=
101        # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist
102        # in libc. IRIX 6.5 has the first one in both libc and libpthread, but
103        # the second one only in libpthread, and lock.c needs it.
104        AC_TRY_LINK([#include <pthread.h>],
105          [pthread_mutex_lock((pthread_mutex_t*)0);
106           pthread_mutexattr_init((pthread_mutexattr_t*)0);],
107          [gl_have_pthread=yes])
108        # Test for libpthread by looking for pthread_kill. (Not pthread_self,
109        # since it is defined as a macro on OSF/1.)
110        if test -n "$gl_have_pthread"; then
111          # The program links fine without libpthread. But it may actually
112          # need to link with libpthread in order to create multiple threads.
113          AC_CHECK_LIB(pthread, pthread_kill,
114            [LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread
115             # On Solaris and HP-UX, most pthread functions exist also in libc.
116             # Therefore pthread_in_use() needs to actually try to create a
117             # thread: pthread_create from libc will fail, whereas
118             # pthread_create will actually create a thread.
119             case "$host_os" in
120               solaris* | hpux*)
121                 AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], 1,
122                   [Define if the pthread_in_use() detection is hard.])
123             esac
124            ])
125        else
126          # Some library is needed. Try libpthread and libc_r.
127          AC_CHECK_LIB(pthread, pthread_kill,
128            [gl_have_pthread=yes
129             LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread
130             LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread])
131          if test -z "$gl_have_pthread"; then
132            # For FreeBSD 4.
133            AC_CHECK_LIB(c_r, pthread_kill,
134              [gl_have_pthread=yes
135               LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r
136               LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r])
137          fi
138        fi
139        if test -n "$gl_have_pthread"; then
140          gl_threads_api=posix
141          AC_DEFINE([USE_POSIX_THREADS], 1,
142            [Define if the POSIX multithreading library can be used.])
143          if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
144            if test $gl_have_weak = yes; then
145              AC_DEFINE([USE_POSIX_THREADS_WEAK], 1,
146                [Define if references to the POSIX multithreading library should be made weak.])
147              LIBTHREAD=
148              LTLIBTHREAD=
149            fi
150          fi
151          # OSF/1 4.0 and MacOS X 10.1 lack the pthread_rwlock_t type and the
152          # pthread_rwlock_* functions.
153          AC_CHECK_TYPE([pthread_rwlock_t],
154            [AC_DEFINE([HAVE_PTHREAD_RWLOCK], 1,
155               [Define if the POSIX multithreading library has read/write locks.])],
156            [],
157            [#include <pthread.h>])
158          # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
159          AC_TRY_COMPILE([#include <pthread.h>],
160            [#if __FreeBSD__ == 4
161error "No, in FreeBSD 4.0 recursive mutexes actually don't work."
162#else
163int x = (int)PTHREAD_MUTEX_RECURSIVE;
164return !x;
165#endif],
166            [AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE], 1,
167               [Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE.])])
168        fi
169      fi
170    fi
171    if test -z "$gl_have_pthread"; then
172      if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then
173        gl_have_solaristhread=
174        gl_save_LIBS="$LIBS"
175        LIBS="$LIBS -lthread"
176        AC_TRY_LINK([#include <thread.h>
177#include <synch.h>],
178          [thr_self();],
179          [gl_have_solaristhread=yes])
180        LIBS="$gl_save_LIBS"
181        if test -n "$gl_have_solaristhread"; then
182          gl_threads_api=solaris
183          LIBTHREAD=-lthread
184          LTLIBTHREAD=-lthread
185          LIBMULTITHREAD="$LIBTHREAD"
186          LTLIBMULTITHREAD="$LTLIBTHREAD"
187          AC_DEFINE([USE_SOLARIS_THREADS], 1,
188            [Define if the old Solaris multithreading library can be used.])
189          if test $gl_have_weak = yes; then
190            AC_DEFINE([USE_SOLARIS_THREADS_WEAK], 1,
191              [Define if references to the old Solaris multithreading library should be made weak.])
192            LIBTHREAD=
193            LTLIBTHREAD=
194          fi
195        fi
196      fi
197    fi
198    if test "$gl_use_threads" = pth; then
199      gl_save_CPPFLAGS="$CPPFLAGS"
200      AC_LIB_LINKFLAGS(pth)
201      gl_have_pth=
202      gl_save_LIBS="$LIBS"
203      LIBS="$LIBS -lpth"
204      AC_TRY_LINK([#include <pth.h>], [pth_self();], gl_have_pth=yes)
205      LIBS="$gl_save_LIBS"
206      if test -n "$gl_have_pth"; then
207        gl_threads_api=pth
208        LIBTHREAD="$LIBPTH"
209        LTLIBTHREAD="$LTLIBPTH"
210        LIBMULTITHREAD="$LIBTHREAD"
211        LTLIBMULTITHREAD="$LTLIBTHREAD"
212        AC_DEFINE([USE_PTH_THREADS], 1,
213          [Define if the GNU Pth multithreading library can be used.])
214        if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
215          if test $gl_have_weak = yes; then
216            AC_DEFINE([USE_PTH_THREADS_WEAK], 1,
217              [Define if references to the GNU Pth multithreading library should be made weak.])
218            LIBTHREAD=
219            LTLIBTHREAD=
220          fi
221        fi
222      else
223        CPPFLAGS="$gl_save_CPPFLAGS"
224      fi
225    fi
226    if test -z "$gl_have_pthread"; then
227      if test "$gl_use_threads" = yes || test "$gl_use_threads" = win32; then
228        if { case "$host_os" in
229               mingw*) true;;
230               *) false;;
231             esac
232           }; then
233          gl_threads_api=win32
234          AC_DEFINE([USE_WIN32_THREADS], 1,
235            [Define if the Win32 multithreading API can be used.])
236        fi
237      fi
238    fi
239  fi
240  AC_MSG_CHECKING([for multithread API to use])
241  AC_MSG_RESULT([$gl_threads_api])
242  AC_SUBST(LIBTHREAD)
243  AC_SUBST(LTLIBTHREAD)
244  AC_SUBST(LIBMULTITHREAD)
245  AC_SUBST(LTLIBMULTITHREAD)
246])
247
248AC_DEFUN([gl_LOCK],
249[
250  AC_REQUIRE([gl_LOCK_EARLY])
251  AC_REQUIRE([gl_LOCK_BODY])
252  gl_PREREQ_LOCK
253])
254
255# Prerequisites of lib/lock.c.
256AC_DEFUN([gl_PREREQ_LOCK], [
257  AC_REQUIRE([AC_C_INLINE])
258])
259
260dnl Survey of platforms:
261dnl
262dnl Platform          Available   Compiler    Supports   test-lock
263dnl                   flavours    option      weak       result
264dnl ---------------   ---------   ---------   --------   ---------
265dnl Linux 2.4/glibc   posix       -lpthread       Y      OK
266dnl
267dnl GNU Hurd/glibc    posix
268dnl
269dnl FreeBSD 5.3       posix       -lc_r           Y
270dnl                   posix       -lkse ?         Y
271dnl                   posix       -lpthread ?     Y
272dnl                   posix       -lthr           Y
273dnl
274dnl FreeBSD 5.2       posix       -lc_r           Y
275dnl                   posix       -lkse           Y
276dnl                   posix       -lthr           Y
277dnl
278dnl FreeBSD 4.0,4.10  posix       -lc_r           Y      OK
279dnl
280dnl NetBSD 1.6        --
281dnl
282dnl OpenBSD 3.4       posix       -lpthread       Y      OK
283dnl
284dnl MacOS X 10.[123]  posix       -lpthread       Y      OK
285dnl
286dnl Solaris 7,8,9     posix       -lpthread       Y      Sol 7,8: 0.0; Sol 9: OK
287dnl                   solaris     -lthread        Y      Sol 7,8: 0.0; Sol 9: OK
288dnl
289dnl HP-UX 11          posix       -lpthread       N (cc) OK
290dnl                                               Y (gcc)
291dnl
292dnl IRIX 6.5          posix       -lpthread       Y      0.5
293dnl
294dnl AIX 4.3,5.1       posix       -lpthread       N      AIX 4: 0.5; AIX 5: OK
295dnl
296dnl OSF/1 4.0,5.1     posix       -pthread (cc)   N      OK
297dnl                               -lpthread (gcc) Y
298dnl
299dnl Cygwin            posix       -lpthread       Y      OK
300dnl
301dnl Any of the above  pth         -lpth                  0.0
302dnl
303dnl Mingw             win32                       N      OK
304dnl
305dnl BeOS 5            --
306dnl
307dnl The test-lock result shows what happens if in test-lock.c EXPLICIT_YIELD is
308dnl turned off:
309dnl   OK if all three tests terminate OK,
310dnl   0.5 if the first test terminates OK but the second one loops endlessly,
311dnl   0.0 if the first test already loops endlessly.
312