Blame m4/lock.m4

Packit f546b1
# lock.m4 serial 7 (gettext-0.17)
Packit f546b1
dnl Copyright (C) 2005-2007 Free Software Foundation, Inc.
Packit f546b1
dnl This file is free software; the Free Software Foundation
Packit f546b1
dnl gives unlimited permission to copy and/or distribute it,
Packit f546b1
dnl with or without modifications, as long as this notice is preserved.
Packit f546b1
Packit f546b1
dnl From Bruno Haible.
Packit f546b1
Packit f546b1
dnl Tests for a multithreading library to be used.
Packit f546b1
dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS,
Packit f546b1
dnl USE_PTH_THREADS, USE_WIN32_THREADS
Packit f546b1
dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use
Packit f546b1
dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with
Packit f546b1
dnl libtool).
Packit f546b1
dnl Sets the variables LIBMULTITHREAD and LTLIBMULTITHREAD similarly, for
Packit f546b1
dnl programs that really need multithread functionality. The difference
Packit f546b1
dnl between LIBTHREAD and LIBMULTITHREAD is that on platforms supporting weak
Packit f546b1
dnl symbols, typically LIBTHREAD="" whereas LIBMULTITHREAD="-lpthread".
Packit f546b1
dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for
Packit f546b1
dnl multithread-safe programs.
Packit f546b1
Packit f546b1
AC_DEFUN([gl_LOCK_EARLY],
Packit f546b1
[
Packit f546b1
  AC_REQUIRE([gl_LOCK_EARLY_BODY])
Packit f546b1
])
Packit f546b1
Packit f546b1
dnl The guts of gl_LOCK_EARLY. Needs to be expanded only once.
Packit f546b1
Packit f546b1
AC_DEFUN([gl_LOCK_EARLY_BODY],
Packit f546b1
[
Packit f546b1
  dnl Ordering constraints: This macro modifies CPPFLAGS in a way that
Packit f546b1
  dnl influences the result of the autoconf tests that test for *_unlocked
Packit f546b1
  dnl declarations, on AIX 5 at least. Therefore it must come early.
Packit f546b1
  AC_BEFORE([$0], [gl_FUNC_GLIBC_UNLOCKED_IO])dnl
Packit f546b1
  AC_BEFORE([$0], [gl_ARGP])dnl
Packit f546b1
Packit f546b1
  AC_REQUIRE([AC_CANONICAL_HOST])
Packit f546b1
  dnl _GNU_SOURCE is needed for pthread_rwlock_t on glibc systems.
Packit f546b1
  dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes
Packit f546b1
  dnl AC_GNU_SOURCE.
Packit f546b1
  m4_ifdef([AC_USE_SYSTEM_EXTENSIONS],
Packit f546b1
    [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])],
Packit f546b1
    [AC_REQUIRE([AC_GNU_SOURCE])])
Packit f546b1
  dnl Check for multithreading.
Packit f546b1
  AC_ARG_ENABLE(threads,
Packit f546b1
AC_HELP_STRING([--enable-threads={posix|solaris|pth|win32}], [specify multithreading API])
Packit f546b1
AC_HELP_STRING([--disable-threads], [build without multithread safety]),
Packit f546b1
    [gl_use_threads=$enableval],
Packit f546b1
    [case "$host_os" in
Packit f546b1
       dnl Disable multithreading by default on OSF/1, because it interferes
Packit f546b1
       dnl with fork()/exec(): When msgexec is linked with -lpthread, its child
Packit f546b1
       dnl process gets an endless segmentation fault inside execvp().
Packit f546b1
       osf*) gl_use_threads=no ;;
Packit f546b1
       *)    gl_use_threads=yes ;;
Packit f546b1
     esac
Packit f546b1
    ])
Packit f546b1
  if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
Packit f546b1
    # For using <pthread.h>:
Packit f546b1
    case "$host_os" in
Packit f546b1
      osf*)
Packit f546b1
        # On OSF/1, the compiler needs the flag -D_REENTRANT so that it
Packit f546b1
        # groks <pthread.h>. cc also understands the flag -pthread, but
Packit f546b1
        # we don't use it because 1. gcc-2.95 doesn't understand -pthread,
Packit f546b1
        # 2. putting a flag into CPPFLAGS that has an effect on the linker
Packit f546b1
        # causes the AC_TRY_LINK test below to succeed unexpectedly,
Packit f546b1
        # leading to wrong values of LIBTHREAD and LTLIBTHREAD.
Packit f546b1
        CPPFLAGS="$CPPFLAGS -D_REENTRANT"
Packit f546b1
        ;;
Packit f546b1
    esac
Packit f546b1
    # Some systems optimize for single-threaded programs by default, and
Packit f546b1
    # need special flags to disable these optimizations. For example, the
Packit f546b1
    # definition of 'errno' in <errno.h>.
Packit f546b1
    case "$host_os" in
Packit f546b1
      aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;;
Packit f546b1
      solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;;
Packit f546b1
    esac
Packit f546b1
  fi
Packit f546b1
])
Packit f546b1
Packit f546b1
dnl The guts of gl_LOCK. Needs to be expanded only once.
Packit f546b1
Packit f546b1
AC_DEFUN([gl_LOCK_BODY],
Packit f546b1
[
Packit f546b1
  AC_REQUIRE([gl_LOCK_EARLY_BODY])
Packit f546b1
  gl_threads_api=none
Packit f546b1
  LIBTHREAD=
Packit f546b1
  LTLIBTHREAD=
Packit f546b1
  LIBMULTITHREAD=
Packit f546b1
  LTLIBMULTITHREAD=
Packit f546b1
  if test "$gl_use_threads" != no; then
Packit f546b1
    dnl Check whether the compiler and linker support weak declarations.
Packit f546b1
    AC_MSG_CHECKING([whether imported symbols can be declared weak])
Packit f546b1
    gl_have_weak=no
Packit f546b1
    AC_TRY_LINK([extern void xyzzy ();
Packit f546b1
#pragma weak xyzzy], [xyzzy();], [gl_have_weak=yes])
Packit f546b1
    AC_MSG_RESULT([$gl_have_weak])
Packit f546b1
    if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then
Packit f546b1
      # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that
Packit f546b1
      # it groks <pthread.h>. It's added above, in gl_LOCK_EARLY_BODY.
Packit f546b1
      AC_CHECK_HEADER(pthread.h, gl_have_pthread_h=yes, gl_have_pthread_h=no)
Packit f546b1
      if test "$gl_have_pthread_h" = yes; then
Packit f546b1
        # Other possible tests:
Packit f546b1
        #   -lpthreads (FSU threads, PCthreads)
Packit f546b1
        #   -lgthreads
Packit f546b1
        gl_have_pthread=
Packit f546b1
        # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist
Packit f546b1
        # in libc. IRIX 6.5 has the first one in both libc and libpthread, but
Packit f546b1
        # the second one only in libpthread, and lock.c needs it.
Packit f546b1
        AC_TRY_LINK([#include <pthread.h>],
Packit f546b1
          [pthread_mutex_lock((pthread_mutex_t*)0);
Packit f546b1
           pthread_mutexattr_init((pthread_mutexattr_t*)0);],
Packit f546b1
          [gl_have_pthread=yes])
Packit f546b1
        # Test for libpthread by looking for pthread_kill. (Not pthread_self,
Packit f546b1
        # since it is defined as a macro on OSF/1.)
Packit f546b1
        if test -n "$gl_have_pthread"; then
Packit f546b1
          # The program links fine without libpthread. But it may actually
Packit f546b1
          # need to link with libpthread in order to create multiple threads.
Packit f546b1
          AC_CHECK_LIB(pthread, pthread_kill,
Packit f546b1
            [LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread
Packit f546b1
             # On Solaris and HP-UX, most pthread functions exist also in libc.
Packit f546b1
             # Therefore pthread_in_use() needs to actually try to create a
Packit f546b1
             # thread: pthread_create from libc will fail, whereas
Packit f546b1
             # pthread_create will actually create a thread.
Packit f546b1
             case "$host_os" in
Packit f546b1
               solaris* | hpux*)
Packit f546b1
                 AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], 1,
Packit f546b1
                   [Define if the pthread_in_use() detection is hard.])
Packit f546b1
             esac
Packit f546b1
            ])
Packit f546b1
        else
Packit f546b1
          # Some library is needed. Try libpthread and libc_r.
Packit f546b1
          AC_CHECK_LIB(pthread, pthread_kill,
Packit f546b1
            [gl_have_pthread=yes
Packit f546b1
             LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread
Packit f546b1
             LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread])
Packit f546b1
          if test -z "$gl_have_pthread"; then
Packit f546b1
            # For FreeBSD 4.
Packit f546b1
            AC_CHECK_LIB(c_r, pthread_kill,
Packit f546b1
              [gl_have_pthread=yes
Packit f546b1
               LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r
Packit f546b1
               LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r])
Packit f546b1
          fi
Packit f546b1
        fi
Packit f546b1
        if test -n "$gl_have_pthread"; then
Packit f546b1
          gl_threads_api=posix
Packit f546b1
          AC_DEFINE([USE_POSIX_THREADS], 1,
Packit f546b1
            [Define if the POSIX multithreading library can be used.])
Packit f546b1
          if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
Packit f546b1
            if test $gl_have_weak = yes; then
Packit f546b1
              AC_DEFINE([USE_POSIX_THREADS_WEAK], 1,
Packit f546b1
                [Define if references to the POSIX multithreading library should be made weak.])
Packit f546b1
              LIBTHREAD=
Packit f546b1
              LTLIBTHREAD=
Packit f546b1
            fi
Packit f546b1
          fi
Packit f546b1
          # OSF/1 4.0 and MacOS X 10.1 lack the pthread_rwlock_t type and the
Packit f546b1
          # pthread_rwlock_* functions.
Packit f546b1
          AC_CHECK_TYPE([pthread_rwlock_t],
Packit f546b1
            [AC_DEFINE([HAVE_PTHREAD_RWLOCK], 1,
Packit f546b1
               [Define if the POSIX multithreading library has read/write locks.])],
Packit f546b1
            [],
Packit f546b1
            [#include <pthread.h>])
Packit f546b1
          # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.
Packit f546b1
          AC_TRY_COMPILE([#include <pthread.h>],
Packit f546b1
            [#if __FreeBSD__ == 4
Packit f546b1
error "No, in FreeBSD 4.0 recursive mutexes actually don't work."
Packit f546b1
#else
Packit f546b1
int x = (int)PTHREAD_MUTEX_RECURSIVE;
Packit f546b1
return !x;
Packit f546b1
#endif],
Packit f546b1
            [AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE], 1,
Packit f546b1
               [Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE.])])
Packit f546b1
        fi
Packit f546b1
      fi
Packit f546b1
    fi
Packit f546b1
    if test -z "$gl_have_pthread"; then
Packit f546b1
      if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then
Packit f546b1
        gl_have_solaristhread=
Packit f546b1
        gl_save_LIBS="$LIBS"
Packit f546b1
        LIBS="$LIBS -lthread"
Packit f546b1
        AC_TRY_LINK([#include <thread.h>
Packit f546b1
#include <synch.h>],
Packit f546b1
          [thr_self();],
Packit f546b1
          [gl_have_solaristhread=yes])
Packit f546b1
        LIBS="$gl_save_LIBS"
Packit f546b1
        if test -n "$gl_have_solaristhread"; then
Packit f546b1
          gl_threads_api=solaris
Packit f546b1
          LIBTHREAD=-lthread
Packit f546b1
          LTLIBTHREAD=-lthread
Packit f546b1
          LIBMULTITHREAD="$LIBTHREAD"
Packit f546b1
          LTLIBMULTITHREAD="$LTLIBTHREAD"
Packit f546b1
          AC_DEFINE([USE_SOLARIS_THREADS], 1,
Packit f546b1
            [Define if the old Solaris multithreading library can be used.])
Packit f546b1
          if test $gl_have_weak = yes; then
Packit f546b1
            AC_DEFINE([USE_SOLARIS_THREADS_WEAK], 1,
Packit f546b1
              [Define if references to the old Solaris multithreading library should be made weak.])
Packit f546b1
            LIBTHREAD=
Packit f546b1
            LTLIBTHREAD=
Packit f546b1
          fi
Packit f546b1
        fi
Packit f546b1
      fi
Packit f546b1
    fi
Packit f546b1
    if test "$gl_use_threads" = pth; then
Packit f546b1
      gl_save_CPPFLAGS="$CPPFLAGS"
Packit f546b1
      AC_LIB_LINKFLAGS(pth)
Packit f546b1
      gl_have_pth=
Packit f546b1
      gl_save_LIBS="$LIBS"
Packit f546b1
      LIBS="$LIBS -lpth"
Packit f546b1
      AC_TRY_LINK([#include <pth.h>], [pth_self();], gl_have_pth=yes)
Packit f546b1
      LIBS="$gl_save_LIBS"
Packit f546b1
      if test -n "$gl_have_pth"; then
Packit f546b1
        gl_threads_api=pth
Packit f546b1
        LIBTHREAD="$LIBPTH"
Packit f546b1
        LTLIBTHREAD="$LTLIBPTH"
Packit f546b1
        LIBMULTITHREAD="$LIBTHREAD"
Packit f546b1
        LTLIBMULTITHREAD="$LTLIBTHREAD"
Packit f546b1
        AC_DEFINE([USE_PTH_THREADS], 1,
Packit f546b1
          [Define if the GNU Pth multithreading library can be used.])
Packit f546b1
        if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then
Packit f546b1
          if test $gl_have_weak = yes; then
Packit f546b1
            AC_DEFINE([USE_PTH_THREADS_WEAK], 1,
Packit f546b1
              [Define if references to the GNU Pth multithreading library should be made weak.])
Packit f546b1
            LIBTHREAD=
Packit f546b1
            LTLIBTHREAD=
Packit f546b1
          fi
Packit f546b1
        fi
Packit f546b1
      else
Packit f546b1
        CPPFLAGS="$gl_save_CPPFLAGS"
Packit f546b1
      fi
Packit f546b1
    fi
Packit f546b1
    if test -z "$gl_have_pthread"; then
Packit f546b1
      if test "$gl_use_threads" = yes || test "$gl_use_threads" = win32; then
Packit f546b1
        if { case "$host_os" in
Packit f546b1
               mingw*) true;;
Packit f546b1
               *) false;;
Packit f546b1
             esac
Packit f546b1
           }; then
Packit f546b1
          gl_threads_api=win32
Packit f546b1
          AC_DEFINE([USE_WIN32_THREADS], 1,
Packit f546b1
            [Define if the Win32 multithreading API can be used.])
Packit f546b1
        fi
Packit f546b1
      fi
Packit f546b1
    fi
Packit f546b1
  fi
Packit f546b1
  AC_MSG_CHECKING([for multithread API to use])
Packit f546b1
  AC_MSG_RESULT([$gl_threads_api])
Packit f546b1
  AC_SUBST(LIBTHREAD)
Packit f546b1
  AC_SUBST(LTLIBTHREAD)
Packit f546b1
  AC_SUBST(LIBMULTITHREAD)
Packit f546b1
  AC_SUBST(LTLIBMULTITHREAD)
Packit f546b1
])
Packit f546b1
Packit f546b1
AC_DEFUN([gl_LOCK],
Packit f546b1
[
Packit f546b1
  AC_REQUIRE([gl_LOCK_EARLY])
Packit f546b1
  AC_REQUIRE([gl_LOCK_BODY])
Packit f546b1
  gl_PREREQ_LOCK
Packit f546b1
])
Packit f546b1
Packit f546b1
# Prerequisites of lib/lock.c.
Packit f546b1
AC_DEFUN([gl_PREREQ_LOCK], [
Packit f546b1
  AC_REQUIRE([AC_C_INLINE])
Packit f546b1
])
Packit f546b1
Packit f546b1
dnl Survey of platforms:
Packit f546b1
dnl
Packit f546b1
dnl Platform          Available   Compiler    Supports   test-lock
Packit f546b1
dnl                   flavours    option      weak       result
Packit f546b1
dnl ---------------   ---------   ---------   --------   ---------
Packit f546b1
dnl Linux 2.4/glibc   posix       -lpthread       Y      OK
Packit f546b1
dnl
Packit f546b1
dnl GNU Hurd/glibc    posix
Packit f546b1
dnl
Packit f546b1
dnl FreeBSD 5.3       posix       -lc_r           Y
Packit f546b1
dnl                   posix       -lkse ?         Y
Packit f546b1
dnl                   posix       -lpthread ?     Y
Packit f546b1
dnl                   posix       -lthr           Y
Packit f546b1
dnl
Packit f546b1
dnl FreeBSD 5.2       posix       -lc_r           Y
Packit f546b1
dnl                   posix       -lkse           Y
Packit f546b1
dnl                   posix       -lthr           Y
Packit f546b1
dnl
Packit f546b1
dnl FreeBSD 4.0,4.10  posix       -lc_r           Y      OK
Packit f546b1
dnl
Packit f546b1
dnl NetBSD 1.6        --
Packit f546b1
dnl
Packit f546b1
dnl OpenBSD 3.4       posix       -lpthread       Y      OK
Packit f546b1
dnl
Packit f546b1
dnl MacOS X 10.[123]  posix       -lpthread       Y      OK
Packit f546b1
dnl
Packit f546b1
dnl Solaris 7,8,9     posix       -lpthread       Y      Sol 7,8: 0.0; Sol 9: OK
Packit f546b1
dnl                   solaris     -lthread        Y      Sol 7,8: 0.0; Sol 9: OK
Packit f546b1
dnl
Packit f546b1
dnl HP-UX 11          posix       -lpthread       N (cc) OK
Packit f546b1
dnl                                               Y (gcc)
Packit f546b1
dnl
Packit f546b1
dnl IRIX 6.5          posix       -lpthread       Y      0.5
Packit f546b1
dnl
Packit f546b1
dnl AIX 4.3,5.1       posix       -lpthread       N      AIX 4: 0.5; AIX 5: OK
Packit f546b1
dnl
Packit f546b1
dnl OSF/1 4.0,5.1     posix       -pthread (cc)   N      OK
Packit f546b1
dnl                               -lpthread (gcc) Y
Packit f546b1
dnl
Packit f546b1
dnl Cygwin            posix       -lpthread       Y      OK
Packit f546b1
dnl
Packit f546b1
dnl Any of the above  pth         -lpth                  0.0
Packit f546b1
dnl
Packit f546b1
dnl Mingw             win32                       N      OK
Packit f546b1
dnl
Packit f546b1
dnl BeOS 5            --
Packit f546b1
dnl
Packit f546b1
dnl The test-lock result shows what happens if in test-lock.c EXPLICIT_YIELD is
Packit f546b1
dnl turned off:
Packit f546b1
dnl   OK if all three tests terminate OK,
Packit f546b1
dnl   0.5 if the first test terminates OK but the second one loops endlessly,
Packit f546b1
dnl   0.0 if the first test already loops endlessly.