* 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.
+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.
[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
+])
+
#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.
+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
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 = \
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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 */
+++ /dev/null
-/* 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 */
#include "util.h"
#include "sema.h"
-#include "mutex.h"
+#include "ath.h"
static void
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;
}