2002-06-02 Marcus Brinkmann <marcus@g10code.de>
authorMarcus Brinkmann <mb@g10code.com>
Sun, 2 Jun 2002 19:19:25 +0000 (19:19 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Sun, 2 Jun 2002 19:19:25 +0000 (19:19 +0000)
* configure.ac: Add checks for Pth and pthreads.
* acinclude.m4: Add slightly hacked check for pth (seems to be an
autoconf version problem).

gpgme/
2002-06-02  Marcus Brinkmann  <marcus@g10code.de>

* Makefile.am (ath_components): New variable.
(ath_components_pthread): Likewise.
(ath_components_pth): Likewise.
(system_components): Add ath_componentes.

* ath.h: New file.
* ath.c: Likewise.
* ath-pthread.c: Likewise.
* ath-pth.c: Likewise.
* posix-sema.c (_gpgme_sema_cs_enter): Rework to use the ATH
interface.
* mutex.h: Remove file.

ChangeLog
acinclude.m4
configure.ac
gpgme/ChangeLog
gpgme/Makefile.am
gpgme/ath-pth.c [new file with mode: 0644]
gpgme/ath-pthread.c [new file with mode: 0644]
gpgme/ath.c [new file with mode: 0644]
gpgme/ath.h [new file with mode: 0644]
gpgme/mutex.h [deleted file]
gpgme/posix-sema.c

index 00aa55b92d2a75334867719384ec84a73dee0a92..092e0c2531d5ee81840e4df4c93799d847654f64 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2002-06-02  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac: Add checks for Pth and pthreads.
+       * acinclude.m4: Add slightly hacked check for pth (seems to be an
+       autoconf version problem).
+
 2002-05-21  Werner Koch  <wk@gnupg.org>
 
        * configure.ac (NEED_GPGSM_VERSION): We need gpgsm 0.3.7.
index 7cbdb15b02926c88098b847d68cbfee96522edff..88f2e43fa7f93a1189566e249ccc19a767f34559 100644 (file)
@@ -43,3 +43,407 @@ AC_DEFUN(GNUPG_CHECK_TYPEDEF,
         [Define to 1 if $1 is defined in the <sys/types.h> header file.])
     fi
   ])
+
+dnl ##
+dnl ##  GNU Pth - The GNU Portable Threads
+dnl ##  Copyright (c) 1999-2002 Ralf S. Engelschall <rse@engelschall.com>
+dnl ##
+dnl ##  This file is part of GNU Pth, a non-preemptive thread scheduling
+dnl ##  library which can be found at http://www.gnu.org/software/pth/.
+dnl ##
+dnl ##  This library is free software; you can redistribute it and/or
+dnl ##  modify it under the terms of the GNU Lesser General Public
+dnl ##  License as published by the Free Software Foundation; either
+dnl ##  version 2.1 of the License, or (at your option) any later version.
+dnl ##
+dnl ##  This library is distributed in the hope that it will be useful,
+dnl ##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl ##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl ##  Lesser General Public License for more details.
+dnl ##
+dnl ##  You should have received a copy of the GNU Lesser General Public
+dnl ##  License along with this library; if not, write to the Free Software
+dnl ##  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+dnl ##  USA, or contact Ralf S. Engelschall <rse@engelschall.com>.
+dnl ##
+dnl ##  pth.m4: Autoconf macro for locating GNU Pth from within
+dnl ##          configure.in of third-party software packages
+dnl ##
+
+dnl ##
+dnl ##  Synopsis:
+dnl ##  AC_CHECK_PTH([MIN-VERSION [,          # minimum Pth version, e.g. 1.2.0
+dnl ##                DEFAULT-WITH-PTH [,     # default value for --with-pth option
+dnl ##                DEFAULT-WITH-PTH-TEST [,# default value for --with-pth-test option
+dnl ##                EXTEND-VARS [,          # whether CFLAGS/LDFLAGS/etc are extended
+dnl ##                ACTION-IF-FOUND [,      # action to perform if Pth was found
+dnl ##                ACTION-IF-NOT-FOUND     # action to perform if Pth was not found
+dnl ##                ]]]]]])
+dnl ##  Examples:
+dnl ##  AC_CHECK_PTH(1.2.0)
+dnl ##  AC_CHECK_PTH(1.2.0,,,no,CFLAGS="$CFLAGS -DHAVE_PTH $PTH_CFLAGS")
+dnl ##  AC_CHECK_PTH(1.2.0,yes,yes,yes,CFLAGS="$CFLAGS -DHAVE_PTH")
+dnl ##
+dnl
+dnl #   auxilliary macros
+AC_DEFUN(_AC_PTH_ERROR, [dnl
+AC_MSG_RESULT([*FAILED*])
+dnl define(_ac_pth_line,dnl
+dnl "+------------------------------------------------------------------------+")
+dnl echo " _ac_pth_line" 1>&2
+cat <<EOT | sed -e 's/^[[      ]]*/ | /' -e 's/>>/  /' 1>&2
+$1
+EOT
+dnl echo " _ac_pth_line" 1>&2
+dnl undefine(_ac_pth_line)
+exit 1
+])
+AC_DEFUN(_AC_PTH_VERBOSE, [dnl
+if test ".$verbose" = .yes; then
+    AC_MSG_RESULT([  $1])
+fi
+])
+dnl #   the user macro
+AC_DEFUN(AC_CHECK_PTH, [dnl
+dnl
+dnl #   prerequisites
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_CPP])dnl
+dnl
+PTH_CPPFLAGS=''
+PTH_CFLAGS=''
+PTH_LDFLAGS=''
+PTH_LIBS=''
+AC_SUBST(PTH_CPPFLAGS)
+AC_SUBST(PTH_CFLAGS)
+AC_SUBST(PTH_LDFLAGS)
+AC_SUBST(PTH_LIBS)
+dnl #   command line options
+AC_MSG_CHECKING(for GNU Pth)
+_AC_PTH_VERBOSE([])
+AC_ARG_WITH(pth,dnl
+[  --with-pth[=ARG]        Build with GNU Pth Library  (default=]ifelse([$2],,yes,$2)[)],dnl
+,dnl
+with_pth="ifelse([$2],,yes,$2)"
+)dnl
+AC_ARG_WITH(pth-test,dnl
+[  --with-pth-test         Perform GNU Pth Sanity Test (default=]ifelse([$3],,yes,$3)[)],dnl
+,dnl
+with_pth_test="ifelse([$3],,yes,$3)"
+)dnl
+_AC_PTH_VERBOSE([+ Command Line Options:])
+_AC_PTH_VERBOSE([    o --with-pth=$with_pth])
+_AC_PTH_VERBOSE([    o --with-pth-test=$with_pth_test])
+dnl
+dnl #   configuration
+if test ".$with_pth" != .no; then
+    _pth_subdir=no
+    _pth_subdir_opts=''
+    case "$with_pth" in
+        subdir:* )
+            _pth_subdir=yes
+            changequote(, )dnl
+            _pth_subdir_opts=`echo $with_pth | sed -e 's/^subdir:[^    ]*[     ]*//'`
+            with_pth=`echo $with_pth | sed -e 's/^subdir:\([^  ]*\).*$/\1/'`
+            changequote([, ])dnl
+            ;;
+    esac
+    _pth_version=""
+    _pth_location=""
+    _pth_type=""
+    _pth_cppflags=""
+    _pth_cflags=""
+    _pth_ldflags=""
+    _pth_libs=""
+    if test ".$with_pth" = .yes; then
+        #   via config script in $PATH
+        changequote(, )dnl
+        _pth_version=`(pth-config --version) 2>/dev/null |\
+                      sed -e 's/^.*\([0-9]\.[0-9]*[ab.][0-9]*\).*$/\1/'`
+        changequote([, ])dnl
+        if test ".$_pth_version" != .; then
+            _pth_location=`pth-config --prefix`
+            _pth_type='installed'
+            _pth_cppflags=`pth-config --cflags`
+            _pth_cflags=`pth-config --cflags`
+            _pth_ldflags=`pth-config --ldflags`
+            _pth_libs=`pth-config --libs`
+        fi
+    elif test -d "$with_pth"; then
+        with_pth=`echo $with_pth | sed -e 's;/*$;;'`
+        _pth_found=no
+        #   via locally included source tree
+        if test ".$_pth_subdir" = .yes; then
+            _pth_location="$with_pth"
+            _pth_type='local'
+            _pth_cppflags="-I$with_pth"
+            _pth_cflags="-I$with_pth"
+            if test -f "$with_pth/ltconfig"; then
+                _pth_ldflags="-L$with_pth/.libs"
+            else
+                _pth_ldflags="-L$with_pth"
+            fi
+            _pth_libs="-lpth"
+            changequote(, )dnl
+            _pth_version=`grep '^const char PTH_Hello' $with_pth/pth_vers.c |\
+                          sed -e 's;^.*Version[        ]*\([0-9]*\.[0-9]*[.ab][0-9]*\)[        ].*$;\1;'`
+            changequote([, ])dnl
+            _pth_found=yes
+            ac_configure_args="$ac_configure_args --enable-subdir $_pth_subdir_opts"
+            with_pth_test=no
+        fi
+        #   via config script under a specified directory
+        #   (a standard installation, but not a source tree)
+        if test ".$_pth_found" = .no; then
+            for _dir in $with_pth/bin $with_pth; do
+                if test -f "$_dir/pth-config"; then
+                    test -f "$_dir/pth-config.in" && continue # pth-config in source tree!
+                    changequote(, )dnl
+                    _pth_version=`($_dir/pth-config --version) 2>/dev/null |\
+                                  sed -e 's/^.*\([0-9]\.[0-9]*[ab.][0-9]*\).*$/\1/'`
+                    changequote([, ])dnl
+                    if test ".$_pth_version" != .; then
+                        _pth_location=`$_dir/pth-config --prefix`
+                        _pth_type="installed"
+                        _pth_cppflags=`$_dir/pth-config --cflags`
+                        _pth_cflags=`$_dir/pth-config --cflags`
+                        _pth_ldflags=`$_dir/pth-config --ldflags`
+                        _pth_libs=`$_dir/pth-config --libs`
+                        _pth_found=yes
+                        break
+                    fi
+                fi
+            done
+        fi
+        #   in any subarea under a specified directory
+        #   (either a special installation or a Pth source tree)
+        if test ".$_pth_found" = .no; then
+            changequote(, )dnl
+            _pth_found=0
+            for _file in x `find $with_pth -name "pth.h" -type f -print`; do
+                test .$_file = .x && continue
+                _dir=`echo $_file | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;'`
+                _pth_version=`($_dir/pth-config --version) 2>/dev/null |\
+                              sed -e 's/^.*\([0-9]\.[0-9]*[ab.][0-9]*\).*$/\1/'`
+                if test ".$_pth_version" = .; then
+                    _pth_version=`grep '^#define PTH_VERSION_STR' $_file |\
+                                  sed -e 's;^#define[  ]*PTH_VERSION_STR[      ]*"\([0-9]*\.[0-9]*[.ab][0-9]*\)[       ].*$;\1;'`
+                fi
+                _pth_cppflags="-I$_dir"
+                _pth_cflags="-I$_dir"
+                _pth_found=`expr $_pth_found + 1`
+            done
+            for _file in x `find $with_pth -name "libpth.[aso]" -type f -print`; do
+                test .$_file = .x && continue
+                _dir=`echo $_file | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;'`
+                _pth_ldflags="-L$_dir"
+                _pth_libs="-lpth"
+                _pth_found=`expr $_pth_found + 1`
+            done
+            changequote([, ])dnl
+            if test ".$_pth_found" = .2; then
+                _pth_location="$with_pth"
+                _pth_type="uninstalled"
+            else
+                _pth_version=''
+            fi
+        fi
+    fi
+    _AC_PTH_VERBOSE([+ Determined Location:])
+    _AC_PTH_VERBOSE([    o path: $_pth_location])
+    _AC_PTH_VERBOSE([    o type: $_pth_type])
+    if test ".$_pth_version" = .; then
+        if test ".$with_pth" != .yes; then
+             _AC_PTH_ERROR([dnl
+             Unable to locate GNU Pth under $with_pth.
+             Please specify the correct path to either a GNU Pth installation tree
+             (use --with-pth=DIR if you used --prefix=DIR for installing GNU Pth in
+             the past) or to a GNU Pth source tree (use --with-pth=DIR if DIR is a
+             path to a pth-X.Y.Z/ directory; but make sure the package is already
+             built, i.e., the "configure; make" step was already performed there).])
+        else
+             _AC_PTH_ERROR([dnl
+             Unable to locate GNU Pth in any system-wide location (see \$PATH).
+             Please specify the correct path to either a GNU Pth installation tree
+             (use --with-pth=DIR if you used --prefix=DIR for installing GNU Pth in
+             the past) or to a GNU Pth source tree (use --with-pth=DIR if DIR is a
+             path to a pth-X.Y.Z/ directory; but make sure the package is already
+             built, i.e., the "configure; make" step was already performed there).])
+        fi
+    fi
+    dnl #
+    dnl #  Check whether the found version is sufficiently new
+    dnl #
+    _req_version="ifelse([$1],,1.0.0,$1)"
+    for _var in _pth_version _req_version; do
+        eval "_val=\"\$${_var}\""
+        _major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\1/'`
+        _minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\2/'`
+        _rtype=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\3/'`
+        _micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\4/'`
+        case $_rtype in
+            "a" ) _rtype=0 ;;
+            "b" ) _rtype=1 ;;
+            "." ) _rtype=2 ;;
+        esac
+        _hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \
+              "major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"`
+        eval "${_var}_hex=\"\$_hex\""
+    done
+    _AC_PTH_VERBOSE([+ Determined Versions:])
+    _AC_PTH_VERBOSE([    o existing: $_pth_version -> 0x$_pth_version_hex])
+    _AC_PTH_VERBOSE([    o required: $_req_version -> 0x$_req_version_hex])
+    _ok=0
+    if test ".$_pth_version_hex" != .; then
+        if test ".$_req_version_hex" != .; then
+            if test $_pth_version_hex -ge $_req_version_hex; then
+                _ok=1
+            fi
+        fi
+    fi
+    if test ".$_ok" = .0; then
+        _AC_PTH_ERROR([dnl
+        Found Pth version $_pth_version, but required at least version $_req_version.
+        Upgrade Pth under $_pth_location to $_req_version or higher first, please.])
+    fi
+    dnl #
+    dnl #   Perform Pth Sanity Compile Check
+    dnl #
+    if test ".$with_pth_test" = .yes; then
+        _ac_save_CPPFLAGS="$CPPFLAGS"
+        _ac_save_CFLAGS="$CFLAGS"
+        _ac_save_LDFLAGS="$LDFLAGS"
+        _ac_save_LIBS="$LIBS"
+        CPPFLAGS="$CPPFLAGS $_pth_cppflags"
+        CFLAGS="$CFLAGS $_pth_cflags"
+        LDFLAGS="$LDFLAGS $_pth_ldflags"
+        LIBS="$LIBS $_pth_libs"
+        _AC_PTH_VERBOSE([+ Test Build Environment:])
+        _AC_PTH_VERBOSE([    o CPPFLAGS=\"$CPPFLAGS\"])
+        _AC_PTH_VERBOSE([    o CFLAGS=\"$CFLAGS\"])
+        _AC_PTH_VERBOSE([    o LDFLAGS=\"$LDFLAGS\"])
+        _AC_PTH_VERBOSE([    o LIBS=\"$LIBS\"])
+        cross_compile=no
+        define(_code1, [dnl
+        #include <stdio.h>
+        #include <pth.h>
+        ])
+        define(_code2, [dnl
+        int main(int argc, char *argv[])
+        {
+            FILE *fp;
+            if (!(fp = fopen("conftestval", "w")))
+                exit(1);
+            fprintf(fp, "hmm");
+            fclose(fp);
+            pth_init();
+            pth_kill();
+            if (!(fp = fopen("conftestval", "w")))
+                exit(1);
+            fprintf(fp, "yes");
+            fclose(fp);
+            exit(0);
+        }
+        ])
+        _AC_PTH_VERBOSE([+ Performing Sanity Checks:])
+        _AC_PTH_VERBOSE([    o pre-processor test])
+        AC_TRY_CPP(_code1, _ok=yes, _ok=no)
+        if test ".$_ok" != .yes; then
+            _AC_PTH_ERROR([dnl
+            Found GNU Pth $_pth_version under $_pth_location, but
+            was unable to perform a sanity pre-processor check. This means
+            the GNU Pth header pth.h was not found.
+            We used the following build environment:
+            >> CPP="$CPP"
+            >> CPPFLAGS="$CPPFLAGS"
+            See config.log for possibly more details.])
+        fi
+        _AC_PTH_VERBOSE([    o link check])
+        AC_TRY_LINK(_code1, _code2, _ok=yes, _ok=no)
+        if test ".$_ok" != .yes; then
+            _AC_PTH_ERROR([dnl
+            Found GNU Pth $_pth_version under $_pth_location, but
+            was unable to perform a sanity linker check. This means
+            the GNU Pth library libpth.a was not found.
+            We used the following build environment:
+            >> CC="$CC"
+            >> CFLAGS="$CFLAGS"
+            >> LDFLAGS="$LDFLAGS"
+            >> LIBS="$LIBS"
+            See config.log for possibly more details.])
+        fi
+        _AC_PTH_VERBOSE([    o run-time check])
+        AC_TRY_RUN(_code1 _code2, _ok=`cat conftestval`, _ok=no, _ok=no)
+        if test ".$_ok" != .yes; then
+            if test ".$_ok" = .no; then
+                _AC_PTH_ERROR([dnl
+                Found GNU Pth $_pth_version under $_pth_location, but
+                was unable to perform a sanity execution check. This usually
+                means that the GNU Pth shared library libpth.so is present
+                but \$LD_LIBRARY_PATH is incomplete to execute a Pth test.
+                In this case either disable this test via --without-pth-test,
+                or extend \$LD_LIBRARY_PATH, or build GNU Pth as a static
+                library only via its --disable-shared Autoconf option.
+                We used the following build environment:
+                >> CC="$CC"
+                >> CFLAGS="$CFLAGS"
+                >> LDFLAGS="$LDFLAGS"
+                >> LIBS="$LIBS"
+                See config.log for possibly more details.])
+            else
+                _AC_PTH_ERROR([dnl
+                Found GNU Pth $_pth_version under $_pth_location, but
+                was unable to perform a sanity run-time check. This usually
+                means that the GNU Pth library failed to work and possibly
+                caused a core dump in the test program. In this case it
+                is strongly recommended that you re-install GNU Pth and this
+                time make sure that it really passes its "make test" procedure.
+                We used the following build environment:
+                >> CC="$CC"
+                >> CFLAGS="$CFLAGS"
+                >> LDFLAGS="$LDFLAGS"
+                >> LIBS="$LIBS"
+                See config.log for possibly more details.])
+            fi
+        fi
+        _extendvars="ifelse([$4],,yes,$4)"
+        if test ".$_extendvars" != .yes; then
+            CPPFLAGS="$_ac_save_CPPFLAGS"
+            CFLAGS="$_ac_save_CFLAGS"
+            LDFLAGS="$_ac_save_LDFLAGS"
+            LIBS="$_ac_save_LIBS"
+        fi
+    else
+        _extendvars="ifelse([$4],,yes,$4)"
+        if test ".$_extendvars" = .yes; then
+            if test ".$_pth_subdir" = .yes; then
+                CPPFLAGS="$CPPFLAGS $_pth_cppflags"
+                CFLAGS="$CFLAGS $_pth_cflags"
+                LDFLAGS="$LDFLAGS $_pth_ldflags"
+                LIBS="$LIBS $_pth_libs"
+            fi
+        fi
+    fi
+    PTH_CPPFLAGS="$_pth_cppflags"
+    PTH_CFLAGS="$_pth_cflags"
+    PTH_LDFLAGS="$_pth_ldflags"
+    PTH_LIBS="$_pth_libs"
+    AC_SUBST(PTH_CPPFLAGS)
+    AC_SUBST(PTH_CFLAGS)
+    AC_SUBST(PTH_LDFLAGS)
+    AC_SUBST(PTH_LIBS)
+    _AC_PTH_VERBOSE([+ Final Results:])
+    _AC_PTH_VERBOSE([    o PTH_CPPFLAGS=\"$PTH_CPPFLAGS\"])
+    _AC_PTH_VERBOSE([    o PTH_CFLAGS=\"$PTH_CFLAGS\"])
+    _AC_PTH_VERBOSE([    o PTH_LDFLAGS=\"$PTH_LDFLAGS\"])
+    _AC_PTH_VERBOSE([    o PTH_LIBS=\"$PTH_LIBS\"])
+fi
+if test ".$with_pth" != .no; then
+    AC_MSG_RESULT([version $_pth_version, $_pth_type under $_pth_location])
+    ifelse([$5], , :, [$5])
+else
+    AC_MSG_RESULT([no])
+    ifelse([$6], , :, [$6])
+fi
+])
+
index 3e160e1a9a34a2e25870a0721d91b347d044215b..afdf4c9055462d0df24c483f7d53e0f91ba9b7b3 100644 (file)
@@ -99,12 +99,24 @@ case "${target}" in
         #component_system='COM+'
         ;;
     *)
+       AC_CHECK_PTH(1.2.0,,,no,have_pth=yes)
+       if test "$have_pth" = yes; then
+         AC_DEFINE(HAVE_PTH, ,[Define if we have Pth.])
+         CFLAGS="$CFLAGS $PTH_CFLAGS"
+       fi
+       AC_CHECK_LIB(pthread,pthread_create,have_pthread=yes)
+       if test "$have_pthread" = yes; then
+         AC_DEFINE(HAVE_PTHREAD, ,[Define if we have pthread.])
+       fi
+
 dnl    # XXX: Probably use exec-prefix here?
 dnl    GPG_DEFAULT='/usr/bin/gpg'
 dnl    GPGSM_DEFAULT='/usr/bin/gpgsm'
        ;;
 esac
 AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = "yes")
+AM_CONDITIONAL(HAVE_PTH, test "$have_pth" = "yes")
+AM_CONDITIONAL(HAVE_PTHREAD, test "$have_pthread" = "yes")
 
 dnl
 dnl Checks for libraries.
index 2cb8c77e4f51df617319e8b01cd5691b4f9e4d71..f8bc8ec8cf5fb36850604788f8a1de23d2103efa 100644 (file)
@@ -1,3 +1,18 @@
+2002-06-02  Marcus Brinkmann  <marcus@g10code.de>
+
+       * Makefile.am (ath_components): New variable.
+       (ath_components_pthread): Likewise.
+       (ath_components_pth): Likewise.
+       (system_components): Add ath_componentes.
+
+       * ath.h: New file.
+       * ath.c: Likewise.
+       * ath-pthread.c: Likewise.
+       * ath-pth.c: Likewise.
+       * posix-sema.c (_gpgme_sema_cs_enter): Rework to use the ATH
+       interface.
+       * mutex.h: Remove file.
+
 2002-05-30  Werner Koch  <wk@gnupg.org>
 
        * key.c (gpgme_key_get_string_attr): Return NULL when asking for
index 93341a14b48270e56952a5ba8e9a99e5cffc588c..42e43e870013a8b7c1a1faf6ac4cec2fb2c6a914 100644 (file)
@@ -35,10 +35,22 @@ AM_CPPFLAGS = -I$(top_srcdir)/assuan
 libgpgme_la_LIBADD = ../assuan/libassuan.la ../jnlib/libjnlib.la
 endif
 
+if HAVE_PTHREAD
+ath_components_pthread = ath-pthread.c
+else
+ath_components_pthread =
+endif
+if HAVE_PTH
+ath_components_pth = ath-pth.c
+else
+ath_components_pth =
+endif
+ath_components = ath.h ath.c ${ath_components_pthread} ${ath_components_pth}
+
 if HAVE_DOSISH_SYSTEM
 system_components = w32-util.c w32-sema.c w32-io.c
 else
-system_components = posix-util.c posix-sema.c posix-io.c
+system_components = ${ath_components} posix-util.c posix-sema.c posix-io.c
 endif
 
 libgpgme_la_SOURCES = \
diff --git a/gpgme/ath-pth.c b/gpgme/ath-pth.c
new file mode 100644 (file)
index 0000000..cac414c
--- /dev/null
@@ -0,0 +1,117 @@
+/* ath-pth.c - Pth module for self-adapting thread-safeness library
+ *      Copyright (C) 2002 g10 Code GmbH
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <malloc.h>
+#include <errno.h>
+#include <pth.h>
+
+#include "ath.h"
+
+#pragma weak pth_mutex_init
+#pragma weak pth_mutex_acquire
+#pragma weak pth_mutex_release
+#pragma weak pth_read
+#pragma weak pth_write
+#pragma weak pth_select
+#pragma weak pth_waitpid
+
+/* The lock we take while checking for lazy lock initialization.  */
+static pth_mutex_t check_init_lock = PTH_MUTEX_INIT;
+
+/* Initialize the mutex *PRIV.  If JUST_CHECK is true, only do this if
+   it is not already initialized.  */
+static int
+mutex_pth_init (void **priv, int just_check)
+{
+  int err = 0;
+
+  if (just_check)
+    pth_mutex_acquire (&check_init_lock, 0, NULL);
+  if (!*priv || !just_check)
+    {
+      pth_mutex_t *lock = malloc (sizeof (pth_mutex_t));
+      if (!lock)
+       err = ENOMEM;
+      if (!err)
+       {
+         err = pth_mutex_init (lock);
+         if (err == FALSE)
+           err = errno;
+         else
+           err = 0;
+
+         if (err)
+           free (lock);
+         else
+           *priv = lock;
+       }
+    }
+  if (just_check)
+    pth_mutex_release (&check_init_lock);
+  return err;
+}
+
+
+static int
+mutex_pth_destroy (void *priv)
+{
+  free (priv);
+  return 0;
+}
+
+
+static int
+mutex_pth_lock (void *priv)
+{
+  int ret = pth_mutex_acquire ((pth_mutex_t *) priv, 0, NULL);
+  return ret == FALSE ? errno : 0;
+}
+
+
+static int
+mutex_pth_unlock (void *priv)
+{
+  int ret = pth_mutex_release ((pth_mutex_t *) priv);
+  return ret == FALSE ? errno : 0;
+}
+
+
+static struct ath_ops ath_pth_ops =
+  {
+    mutex_pth_init,
+    mutex_pth_destroy,
+    mutex_pth_lock,
+    mutex_pth_unlock,
+    pth_read,
+    pth_write,
+    pth_select,
+    pth_waitpid
+  };
+
+
+struct ath_ops *
+ath_pth_available (void)
+{
+  if (pth_mutex_init && pth_mutex_acquire && pth_mutex_release
+      && pth_read && pth_write && pth_select && pth_waitpid)
+    return &ath_pth_ops;
+  else
+    return 0;
+}
diff --git a/gpgme/ath-pthread.c b/gpgme/ath-pthread.c
new file mode 100644 (file)
index 0000000..ec250d8
--- /dev/null
@@ -0,0 +1,100 @@
+/* ath-pthread.c - pthread module for self-adapting thread-safeness library
+ *      Copyright (C) 2002 g10 Code GmbH
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <malloc.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include "ath.h"
+
+/* Need to include pthread_create in our check, as the GNU C library
+   has the pthread_mutex_* functions in their public interface.  */
+#pragma weak pthread_create
+#pragma weak pthread_mutex_init
+#pragma weak pthread_mutex_destroy
+#pragma weak pthread_mutex_lock
+#pragma weak pthread_mutex_unlock
+
+/* The lock we take while checking for lazy lock initialization.  */
+static pthread_mutex_t check_init_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/* Initialize the mutex *PRIV.  If JUST_CHECK is true, only do this if
+   it is not already initialized.  */
+static int
+mutex_pthread_init (void **priv, int just_check)
+{
+  int err = 0;
+
+  if (just_check)
+    pthread_mutex_lock (&check_init_lock);
+  if (!*priv || !just_check)
+    {
+      pthread_mutex_t *lock = malloc (sizeof (pthread_mutex_t));
+      if (!lock)
+       err = ENOMEM;
+      if (!err)
+       {
+         err = pthread_mutex_init (lock, NULL);
+         if (err)
+           free (lock);
+         else
+           *priv = lock;
+       }
+    }
+  if (just_check)
+    pthread_mutex_unlock (&check_init_lock);
+  return err;
+}
+
+
+static int
+mutex_pthread_destroy (void *priv)
+{
+  int err = pthread_mutex_destroy ((pthread_mutex_t *) priv);
+  free (priv);
+  return err;
+}
+
+
+static struct ath_ops ath_pthread_ops =
+  {
+    mutex_pthread_init,
+    mutex_pthread_destroy,
+    (int (*) (void *)) pthread_mutex_lock,
+    (int (*) (void *)) pthread_mutex_unlock,
+    NULL,      /* read */
+    NULL,      /* write */
+    NULL,      /* select */
+    NULL       /* waitpid */
+  };
+
+
+struct ath_ops *
+ath_pthread_available (void)
+{
+  /* Need to include pthread_create in our check, as the GNU C library
+     has the pthread_mutex_* functions in their public interface.  */
+  if (pthread_create
+      && pthread_mutex_init && pthread_mutex_destroy
+      && pthread_mutex_lock && pthread_mutex_unlock)
+    return &ath_pthread_ops;
+  else
+    return 0;
+}
diff --git a/gpgme/ath.c b/gpgme/ath.c
new file mode 100644 (file)
index 0000000..e685031
--- /dev/null
@@ -0,0 +1,141 @@
+/* ath.c - self-adapting thread-safeness library
+ *      Copyright (C) 2002 g10 Code GmbH
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "ath.h"
+
+static struct ath_ops *ath_ops;
+
+void
+ath_init (void)
+{
+#ifdef HAVE_PTHREAD
+  if (!ath_ops)
+    ath_ops = ath_pthread_available ();
+#endif
+#ifdef HAVE_PTH
+  if (!ath_ops)
+    ath_ops = ath_pth_available ();
+#endif
+#ifdef HAVE_ATH_DUMMY
+  if (!ath_ops)
+    ath_ops = ath_dummy_available ();
+#endif
+}
+
+
+int
+ath_mutex_init (ath_mutex_t *lock)
+{
+  if (!ath_ops)
+    return 0;
+
+  return ath_ops->mutex_init (lock, 0);
+}
+
+
+int
+ath_mutex_destroy (ath_mutex_t *lock)
+{
+  int err;
+  if (!ath_ops)
+    return 0;
+  err = ath_ops->mutex_init (lock, 1);
+  if (!err)
+    err = ath_ops->mutex_destroy (*lock);
+  return err;
+}
+
+
+int
+ath_mutex_lock (ath_mutex_t *lock)
+{
+  int err;
+
+  if (!ath_ops)
+    return 0;
+  err = ath_ops->mutex_init (lock, 1);
+  if (!err)
+    err = ath_ops->mutex_lock (*lock);
+  return err;
+}
+
+
+int
+ath_mutex_unlock (ath_mutex_t *lock)
+{
+  int err;
+
+  if (!ath_ops)
+    return 0;
+  err = ath_ops->mutex_init (lock, 1);
+  if (!err)
+    err = ath_ops->mutex_unlock (*lock);
+  return err;
+}
+
+
+ssize_t
+ath_read (int fd, void *buf, size_t nbytes)
+{
+  if (ath_ops && ath_ops->read)
+    return ath_ops->read (fd, buf, nbytes);
+  else
+    return read (fd, buf, nbytes);
+}
+
+
+ssize_t
+ath_write (int fd, const void *buf, size_t nbytes)
+{
+  if (ath_ops && ath_ops->write)
+    return ath_ops->write (fd, buf, nbytes);
+  else
+    return write (fd, buf, nbytes);
+}
+
+
+ssize_t
+ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+           struct timeval *timeout)
+{
+  if (ath_ops && ath_ops->select)
+    return ath_ops->select (nfd, rset, wset, eset, timeout);
+  else
+    return select (nfd, rset, wset, eset, timeout);
+}
+
+ssize_t
+ath_waitpid (pid_t pid, int *status, int options)
+{
+  if (ath_ops && ath_ops->waitpid)
+    return ath_ops->waitpid (pid, status, options);
+  else
+    return waitpid (pid, status, options);
+}
diff --git a/gpgme/ath.h b/gpgme/ath.h
new file mode 100644 (file)
index 0000000..c0a8e20
--- /dev/null
@@ -0,0 +1,93 @@
+/* ath.h - interfaces for self-adapting thread-safeness library
+ *      Copyright (C) 2002 g10 Code GmbH
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef ATH_H
+#define ATH_H
+
+#include <sys/types.h>
+
+/* Define ATH_EXT_SYM_PREFIX if you want to give all external symbols
+   a prefix.  */
+/* #define ATH_EXT_SYM_PREFIX _gpgme_ */
+
+#ifdef ATH_EXT_SYM_PREFIX
+#define ath_pkg_init MUTEX_EXT_SYM_PREFIX##ath_pkg_init
+#define ath_mutex_init MUTEX_EXT_SYM_PREFIX##ath_mutex_init
+#define ath_mutex_destroy MUTEX_EXT_SYM_PREFIX##ath_mutex_destroy
+#define ath_mutex_lock MUTEX_EXT_SYM_PREFIX##ath_mutex_lock
+#define ath_mutex_pthread_available \
+  MUTEX_EXT_SYM_PREFIX##ath_mutex_pthread_available
+#define ath_mutex_pth_available \
+  MUTEX_EXT_SYM_PREFIX##ath_mutex_pth_available
+#define ath_mutex_dummy_available \
+  MUTEX_EXT_SYM_PREFIX##ath_mutex_dummy_available
+#define ath_read MUTEX_EXT_SYM##ath_read
+#define ath_write MUTEX_EXT_SYM##ath_write
+#define ath_select MUTEX_EXT_SYM##ath_select
+#define ath_waitpid MUTEX_EXT_SYM##ath_waitpid
+#define ath_mutex_pthread_available \
+  MUTEX_EXT_SYM_PREFIX##ath_mutex_pthread_available
+#define ath_mutex_pthr_available \
+  MUTEX_EXT_SYM_PREFIX##ath_mutex_pthr_available
+#define ath_mutex_dummy_available \
+  MUTEX_EXT_SYM_PREFIX##ath_mutex_dummy_available
+#endif
+
+\f
+typedef void *ath_mutex_t;
+#define ATH_MUTEX_INITIALIZER 0;
+
+/* Functions for mutual exclusion.  */
+int ath_mutex_init (ath_mutex_t *mutex);
+int ath_mutex_destroy (ath_mutex_t *mutex);
+int ath_mutex_lock (ath_mutex_t *mutex);
+int ath_mutex_unlock (ath_mutex_t *mutex);
+
+/* Replacement for the POSIX functions, which can be used to allow
+   other (user-level) threads to run.  */
+ssize_t ath_read (int fd, void *buf, size_t nbytes);
+ssize_t ath_write (int fd, const void *buf, size_t nbytes);
+ssize_t ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+                   struct timeval *timeout);
+ssize_t ath_waitpid (pid_t pid, int *status, int options);
+
+\f
+struct ath_ops
+{
+  int (*mutex_init) (void **priv, int just_check);
+  int (*mutex_destroy) (void *priv);
+  int (*mutex_lock) (void *priv);
+  int (*mutex_unlock) (void *priv);
+  ssize_t (*read) (int fd, void *buf, size_t nbytes);
+  ssize_t (*write) (int fd, const void *buf, size_t nbytes);
+  ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+                    struct timeval *timeout);
+  ssize_t (*waitpid) (pid_t pid, int *status, int options);
+};
+
+/* Initialize the any-thread package.  */
+void ath_init (void);
+
+/* Used by ath_pkg_init.  */
+struct ath_ops *ath_pthread_available (void);
+struct ath_ops *ath_pth_available (void);
+struct ath_ops *ath_dummy_available (void);
+
+#endif /* ATH_H */
diff --git a/gpgme/mutex.h b/gpgme/mutex.h
deleted file mode 100644 (file)
index a1cf868..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* mutex.h -  Portable mutual exclusion, independent from any thread library.
- *      Copyright (C) 2002 g10 Code GmbH
- *
- * This file is part of GPGME.
- *
- * GPGME is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GPGME is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef MUTEX_H
-#define MUTEX_H
-
-/* Define MUTEX_FAKE before including the file to get stubs that don't
-   provide any locking at all.  Define MUTEX_PTHREAD if you can link
-   against the posix thread library.  */
-
-#if defined(MUTEX_FAKE)
-
-typedef char mutex_t;
-#define mutex_init(x) (0)
-#define mutex_destroy(x)
-#define mutex_lock(x) (0)
-#define mutex_unlock(x) (0)
-
-#elif defined(MUTEX_PTHREAD)
-
-#include <pthread.h>
-
-#define mutex_t pthread_mutex_t
-#define mutex_init(x) pthread_mutex_init (&(x), 0)
-#define mutex_destroy(x) pthread_mutex_destroy(&(x))
-#define mutex_lock(x) pthread_mutex_lock (&(x))
-#define mutex_unlock(x) pthread_mutex_unlock (&(x))
-
-#else
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-/* The type of a mutex.  */
-typedef int mutex_t[2];
-
-inline static int
-set_close_on_exec (int fd)
-{
-  int flags = fcntl (fd, F_GETFD, 0);
-  if (flags == -1)
-    return errno;
-  flags |= FD_CLOEXEC;
-  if (fcntl (fd, F_SETFD, flags) == -1)
-    return errno;
-  return 0;
-}
-
-/* Initialize the mutex variable MUTEX.  */
-inline int
-mutex_init (mutex_t mutex)
-{
-  ssize_t amount;
-  int err = 0;
-
-  if (pipe (mutex))
-    return errno;
-
-  err = set_close_on_exec (mutex[0]);
-  if (!err)
-    err = set_close_on_exec (mutex[1]);
-  if (!err)
-    while ((amount = write (mutex[1], " ", 1)) < 0 && errno == EINTR)
-      ;
-  if (!err && amount != 1)
-    err = errno;
-
-  if (err)
-    {
-      close (mutex[0]);
-      close (mutex[1]);
-    }
-  return err;
-}
-
-/* Destroy the mutex variable MUTEX.  */
-inline void
-mutex_destroy (mutex_t mutex)
-{
-  close (mutex[0]);
-  close (mutex[1]);
-}
-
-/* Take the mutex variable MUTEX.  */
-inline int
-mutex_lock (mutex_t mutex)
-{
-  char data;
-  int amount;
-  while ((amount = read (mutex[0], &data, 1)) < 0 && errno == EINTR)
-    ;
-  return (amount != 1) ? errno : 0;
-}
-
-/* Release the mutex variable MUTEX.  */
-inline int
-mutex_unlock (mutex_t mutex)
-{
-  int amount;
-  while ((amount = write (mutex[1], " ", 1)) < 0 && errno == EINTR)
-    ;
-  return (amount != 1) ? errno : 0;
-}
-
-#endif /* MUTEX_FAKE */
-#endif /* MUTEX_H */
index aff8bbccff62b68a69f8436f4f0aee544a340865..bcb1339de54960f4630285a6910c83d899f01a25 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "util.h"
 #include "sema.h"
-#include "mutex.h"
+#include "ath.h"
 
 static void
 sema_fatal (const char *text)
@@ -44,76 +44,28 @@ sema_fatal (const char *text)
   abort ();
 }
 
-
-static void
-critsect_init (struct critsect_s *s)
-{
-  static mutex_t init_lock;
-  static int initialized;
-  mutex_t *mp;
-    
-  if (!initialized)
-    {
-      /* The very first time we call this function, we assume that
-         only one thread is running, so that we can bootstrap the
-         semaphore code.  */
-      mutex_init (init_lock);
-      initialized = 1;
-    }
-  if (!s)
-    return;    /* We just want to initialize ourself.  */
-  
-  /* First test whether it is really not initialized.  */
-  mutex_lock (init_lock);
-  if (s->private)
-    {
-      mutex_unlock (init_lock);
-      return;
-    }
-  /* Now initialize it.  */
-  mp = xtrymalloc (sizeof *mp);
-  if (!mp)
-    {
-      mutex_unlock (init_lock);
-      sema_fatal ("out of core while creating critical section lock");
-    }
-  mutex_init (*mp);
-  s->private = mp;
-  mutex_unlock (init_lock);
-}
-
-
 void
 _gpgme_sema_subsystem_init ()
 {
   /* FIXME: we should check that there is only one thread running */
-  critsect_init (NULL);
+  ath_init ();
 }
 
-
 void
 _gpgme_sema_cs_enter (struct critsect_s *s)
 {
-  if (!s->private)
-    critsect_init (s);
-  mutex_lock (*((mutex_t *) s->private));
+  ath_mutex_lock (&s->private);
 }
 
 void
 _gpgme_sema_cs_leave (struct critsect_s *s)
 {
-  if (!s->private)
-    critsect_init (s);
-  mutex_unlock (*((mutex_t *) s->private));
+  ath_mutex_unlock (&s->private);
 }
 
 void
 _gpgme_sema_cs_destroy (struct critsect_s *s)
 {
-  if (s && s->private)
-    {
-      mutex_destroy (*((mutex_t *) s->private));
-      xfree (s->private);
-      s->private = NULL;
-    }
+  ath_mutex_destroy (&s->private);
+  s->private = NULL;
 }