Completed switch to a simpler thread model.
authorWerner Koch <wk@gnupg.org>
Thu, 1 Dec 2011 12:55:06 +0000 (13:55 +0100)
committerWerner Koch <wk@gnupg.org>
Thu, 1 Dec 2011 12:59:38 +0000 (13:59 +0100)
This is only a first step.  We will need to either implement
pthread_atfork or - better - make use use POSIX RT semaphores.

18 files changed:
ChangeLog
cipher/ChangeLog
cipher/cipher.c
cipher/md.c
cipher/primegen.c
cipher/pubkey.c
config.rpath [new file with mode: 0755]
configure.ac
random/random-csprng.c
random/random-daemon.c
random/random-fips.c
src/ChangeLog
src/ath.c
src/ath.h
src/fips.c
src/g10lib.h
src/gcrypt.h.in
src/global.c

index 9b55e9d..28eee9f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,10 @@
        accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix
        * m4/gpg-error.m4: Update from git master.
 
+2011-09-16  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (HAVE_PTHREAD): New.
+
 2011-09-15  Werner Koch  <wk@g10code.com>
 
        * configure.ac: Bump LT version at C19/A0/R0 due to the ABI change.
@@ -33,8 +37,6 @@
 
 2011-02-23  Werner Koch  <wk@g10code.com>
 
-       * configure.ac (HAVE_PTHREAD): New.
-
        * configure.ac (LIBGCRYPT_CONFIG_HOST): New.
 
        * acinclude.m4 (AM_PATH_GPG_ERROR): Remove.
index cc59935..18eb9d6 100644 (file)
@@ -1,3 +1,7 @@
+2011-09-16  Werner Koch  <wk@g10code.com>
+
+       * primegen.c (_gcry_primegen_init): New.
+
 2011-09-15  Werner Koch  <wk@g10code.com>
 
        * cipher-cbc.c, cipher-cfb.c, cipher-ofb.c, cipher-ctr.c: New.
index 9bef332..589c262 100644 (file)
@@ -106,8 +106,9 @@ static struct cipher_table_entry
 /* List of registered ciphers.  */
 static gcry_module_t ciphers_registered;
 
-/* This is the lock protecting CIPHERS_REGISTERED.  */
-static ath_mutex_t ciphers_registered_lock = ATH_MUTEX_INITIALIZER;
+/* This is the lock protecting CIPHERS_REGISTERED.  It is initialized
+   by _gcry_cipher_init.  */
+static ath_mutex_t ciphers_registered_lock;
 
 /* Flag to check whether the default ciphers have already been
    registered.  */
@@ -1353,7 +1354,11 @@ gcry_cipher_get_algo_blklen (int algo)
 gcry_err_code_t
 _gcry_cipher_init (void)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t err;
+
+  err = ath_mutex_init (&ciphers_registered_lock);
+  if (err)
+    return gpg_err_code_from_errno (err);
 
   REGISTER_DEFAULT_CIPHERS;
 
index 5ae9aee..46567a1 100644 (file)
@@ -103,7 +103,7 @@ static struct digest_table_entry
 static gcry_module_t digests_registered;
 
 /* This is the lock protecting DIGESTS_REGISTERED.  */
-static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER;
+static ath_mutex_t digests_registered_lock;
 
 /* Flag to check whether the default ciphers have already been
    registered.  */
@@ -1284,7 +1284,11 @@ gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
 gcry_err_code_t
 _gcry_md_init (void)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t err;
+
+  err = ath_mutex_init (&digests_registered_lock);
+  if (err)
+    return gpg_err_code_from_errno (err);
 
   REGISTER_DEFAULT_DIGESTS;
 
index 2788e34..d0cf20c 100644 (file)
@@ -141,9 +141,20 @@ struct primepool_s
 };
 struct primepool_s *primepool;
 /* Mutex used to protect access to the primepool.  */
-static ath_mutex_t primepool_lock = ATH_MUTEX_INITIALIZER;
+static ath_mutex_t primepool_lock;
 
 
+gcry_err_code_t
+_gcry_primegen_init (void)
+{
+  gcry_err_code_t ec;
+
+  ec = ath_mutex_init (&primepool_lock);
+  if (ec)
+    return gpg_err_code_from_errno (ec);
+  return ec;
+}
+
 
 /* Save PRIME which has been generated at RANDOMLEVEL for later
    use. Needs to be called while primepool_lock is being hold.  Note
@@ -195,7 +206,7 @@ save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel)
 
 /* Return a prime for the prime pool or NULL if none has been found.
    The prime needs to match NBITS and randomlevel. This function needs
-   to be called why the primepool_look is being hold. */
+   to be called with the primepool_look is being hold. */
 static gcry_mpi_t
 get_pool_prime (unsigned int nbits, gcry_random_level_t randomlevel)
 {
index afb14c9..c4be81c 100644 (file)
@@ -85,7 +85,7 @@ static struct pubkey_table_entry
 static gcry_module_t pubkeys_registered;
 
 /* This is the lock protecting PUBKEYS_REGISTERED.  */
-static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;;
+static ath_mutex_t pubkeys_registered_lock;
 
 /* Flag to check whether the default pubkeys have already been
    registered.  */
@@ -4056,7 +4056,11 @@ gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
 gcry_err_code_t
 _gcry_pk_init (void)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t err;
+
+  err = ath_mutex_init (&pubkeys_registered_lock);
+  if (err)
+    return gpg_err_code_from_errno (err);
 
   REGISTER_DEFAULT_PUBKEYS;
 
diff --git a/config.rpath b/config.rpath
new file mode 100755 (executable)
index 0000000..c547c68
--- /dev/null
@@ -0,0 +1,666 @@
+#! /bin/sh
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+#   Copyright 1996-2007 Free Software Foundation, Inc.
+#   Taken from GNU libtool, 2001
+#   Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+#   This file is free software; the Free Software Foundation gives
+#   unlimited permission to copy and/or distribute it, with or without
+#   modifications, as long as this notice is preserved.
+#
+# The first argument passed to this file is the canonical host specification,
+#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+#   than 256 bytes, otherwise the compiler driver will dump core. The only
+#   known workaround is to choose shorter directory names for the build
+#   directory and/or the installation directory.
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+  wl='-Wl,'
+else
+  case "$host_os" in
+    aix*)
+      wl='-Wl,'
+      ;;
+    darwin*)
+      case $cc_basename in
+        xlc*)
+          wl='-Wl,'
+          ;;
+      esac
+      ;;
+    mingw* | cygwin* | pw32* | os2*)
+      ;;
+    hpux9* | hpux10* | hpux11*)
+      wl='-Wl,'
+      ;;
+    irix5* | irix6* | nonstopux*)
+      wl='-Wl,'
+      ;;
+    newsos6)
+      ;;
+    linux* | k*bsd*-gnu)
+      case $cc_basename in
+        icc* | ecc*)
+          wl='-Wl,'
+          ;;
+        pgcc | pgf77 | pgf90)
+          wl='-Wl,'
+          ;;
+        ccc*)
+          wl='-Wl,'
+          ;;
+        como)
+          wl='-lopt='
+          ;;
+        *)
+          case `$CC -V 2>&1 | sed 5q` in
+            *Sun\ C*)
+              wl='-Wl,'
+              ;;
+          esac
+          ;;
+      esac
+      ;;
+    osf3* | osf4* | osf5*)
+      wl='-Wl,'
+      ;;
+    rdos*)
+      ;;
+    solaris*)
+      wl='-Wl,'
+      ;;
+    sunos4*)
+      wl='-Qoption ld '
+      ;;
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      wl='-Wl,'
+      ;;
+    sysv4*MP*)
+      ;;
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      wl='-Wl,'
+      ;;
+    unicos*)
+      wl='-Wl,'
+      ;;
+    uts4*)
+      ;;
+  esac
+fi
+
+# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # Set some defaults for GNU ld with shared library support. These
+  # are reset later if shared libraries are not supported. Putting them
+  # here allows them to be overridden if necessary.
+  # Unlike libtool, we use -rpath here, not --rpath, since the documented
+  # option of GNU ld is called -rpath, not --rpath.
+  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+  case "$host_os" in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+        ld_shlibs=no
+      fi
+      ;;
+    amigaos*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we cannot use
+      # them.
+      ld_shlibs=no
+      ;;
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    cygwin* | mingw* | pw32*)
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      ;;
+    gnu* | linux* | k*bsd*-gnu)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    netbsd*)
+      ;;
+    solaris*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+        ld_shlibs=no
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+          ld_shlibs=no
+          ;;
+        *)
+          if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+            hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+          else
+            ld_shlibs=no
+          fi
+          ;;
+      esac
+      ;;
+    sunos4*)
+      hardcode_direct=yes
+      ;;
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        :
+      else
+        ld_shlibs=no
+      fi
+      ;;
+  esac
+  if test "$ld_shlibs" = no; then
+    hardcode_libdir_flag_spec=
+  fi
+else
+  case "$host_os" in
+    aix3*)
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes; then
+        # Neither direct hardcoding nor static linking is supported with a
+        # broken collect2.
+        hardcode_direct=unsupported
+      fi
+      ;;
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+        # On IA64, the linker does run time linking by default, so we don't
+        # have to do anything special.
+        aix_use_runtimelinking=no
+      else
+        aix_use_runtimelinking=no
+        # Test if we are trying to use run time linking or normal
+        # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+        # need to do runtime linking.
+        case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+          for ld_flag in $LDFLAGS; do
+            if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+              aix_use_runtimelinking=yes
+              break
+            fi
+          done
+          ;;
+        esac
+      fi
+      hardcode_direct=yes
+      hardcode_libdir_separator=':'
+      if test "$GCC" = yes; then
+        case $host_os in aix4.[012]|aix4.[012].*)
+          collect2name=`${CC} -print-prog-name=collect2`
+          if test -f "$collect2name" && \
+            strings "$collect2name" | grep resolve_lib_name >/dev/null
+          then
+            # We have reworked collect2
+            :
+          else
+            # We have old collect2
+            hardcode_direct=unsupported
+            hardcode_minus_L=yes
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_libdir_separator=
+          fi
+          ;;
+        esac
+      fi
+      # Begin _LT_AC_SYS_LIBPATH_AIX.
+      echo 'int main () { return 0; }' > conftest.c
+      ${CC} ${LDFLAGS} conftest.c -o conftest
+      aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+      if test -z "$aix_libpath"; then
+        aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+      fi
+      if test -z "$aix_libpath"; then
+        aix_libpath="/usr/lib:/lib"
+      fi
+      rm -f conftest.c conftest
+      # End _LT_AC_SYS_LIBPATH_AIX.
+      if test "$aix_use_runtimelinking" = yes; then
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+      else
+        if test "$host_cpu" = ia64; then
+          hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+        else
+          hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        fi
+      fi
+      ;;
+    amigaos*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs=no
+      ;;
+    bsdi[45]*)
+      ;;
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec=' '
+      libext=lib
+      ;;
+    darwin* | rhapsody*)
+      hardcode_direct=no
+      if test "$GCC" = yes ; then
+        :
+      else
+        case $cc_basename in
+          xlc*)
+            ;;
+          *)
+            ld_shlibs=no
+            ;;
+        esac
+      fi
+      ;;
+    dgux*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      ;;
+    freebsd1*)
+      ld_shlibs=no
+      ;;
+    freebsd2.2*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      ;;
+    freebsd2*)
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      ;;
+    freebsd* | dragonfly*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      ;;
+    hpux9*)
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      ;;
+    hpux10*)
+      if test "$with_gnu_ld" = no; then
+        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator=:
+        hardcode_direct=yes
+        # hardcode_minus_L: Not really in the search PATH,
+        # but as the default location of the library.
+        hardcode_minus_L=yes
+      fi
+      ;;
+    hpux11*)
+      if test "$with_gnu_ld" = no; then
+        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator=:
+        case $host_cpu in
+          hppa*64*|ia64*)
+            hardcode_direct=no
+            ;;
+          *)
+            hardcode_direct=yes
+            # hardcode_minus_L: Not really in the search PATH,
+            # but as the default location of the library.
+            hardcode_minus_L=yes
+            ;;
+        esac
+      fi
+      ;;
+    irix5* | irix6* | nonstopux*)
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+    netbsd*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      ;;
+    newsos6)
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+        hardcode_direct=yes
+        if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+          hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+        else
+          case "$host_os" in
+            openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+              hardcode_libdir_flag_spec='-R$libdir'
+              ;;
+            *)
+              hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+              ;;
+          esac
+        fi
+      else
+        ld_shlibs=no
+      fi
+      ;;
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      ;;
+    osf3*)
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+    osf4* | osf5*)
+      if test "$GCC" = yes; then
+        hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+        # Both cc and cxx compiler support -rpath directly
+        hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      hardcode_libdir_separator=:
+      ;;
+    solaris*)
+      hardcode_libdir_flag_spec='-R$libdir'
+      ;;
+    sunos4*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      ;;
+    sysv4)
+      case $host_vendor in
+        sni)
+          hardcode_direct=yes # is this really true???
+          ;;
+        siemens)
+          hardcode_direct=no
+          ;;
+        motorola)
+          hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+          ;;
+      esac
+      ;;
+    sysv4.3*)
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+        ld_shlibs=yes
+      fi
+      ;;
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      ;;
+    sysv5* | sco3.2v5* | sco5v6*)
+      hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      hardcode_libdir_separator=':'
+      ;;
+    uts4*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      ;;
+    *)
+      ld_shlibs=no
+      ;;
+  esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec=      # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+  aix3*)
+    library_names_spec='$libname.a'
+    ;;
+  aix4* | aix5*)
+    library_names_spec='$libname$shrext'
+    ;;
+  amigaos*)
+    library_names_spec='$libname.a'
+    ;;
+  beos*)
+    library_names_spec='$libname$shrext'
+    ;;
+  bsdi[45]*)
+    library_names_spec='$libname$shrext'
+    ;;
+  cygwin* | mingw* | pw32*)
+    shrext=.dll
+    library_names_spec='$libname.dll.a $libname.lib'
+    ;;
+  darwin* | rhapsody*)
+    shrext=.dylib
+    library_names_spec='$libname$shrext'
+    ;;
+  dgux*)
+    library_names_spec='$libname$shrext'
+    ;;
+  freebsd1*)
+    ;;
+  freebsd* | dragonfly*)
+    case "$host_os" in
+      freebsd[123]*)
+        library_names_spec='$libname$shrext$versuffix' ;;
+      *)
+        library_names_spec='$libname$shrext' ;;
+    esac
+    ;;
+  gnu*)
+    library_names_spec='$libname$shrext'
+    ;;
+  hpux9* | hpux10* | hpux11*)
+    case $host_cpu in
+      ia64*)
+        shrext=.so
+        ;;
+      hppa*64*)
+        shrext=.sl
+        ;;
+      *)
+        shrext=.sl
+        ;;
+    esac
+    library_names_spec='$libname$shrext'
+    ;;
+  interix[3-9]*)
+    library_names_spec='$libname$shrext'
+    ;;
+  irix5* | irix6* | nonstopux*)
+    library_names_spec='$libname$shrext'
+    case "$host_os" in
+      irix5* | nonstopux*)
+        libsuff= shlibsuff=
+        ;;
+      *)
+        case $LD in
+          *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
+          *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
+          *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
+          *) libsuff= shlibsuff= ;;
+        esac
+        ;;
+    esac
+    ;;
+  linux*oldld* | linux*aout* | linux*coff*)
+    ;;
+  linux* | k*bsd*-gnu)
+    library_names_spec='$libname$shrext'
+    ;;
+  knetbsd*-gnu)
+    library_names_spec='$libname$shrext'
+    ;;
+  netbsd*)
+    library_names_spec='$libname$shrext'
+    ;;
+  newsos6)
+    library_names_spec='$libname$shrext'
+    ;;
+  nto-qnx*)
+    library_names_spec='$libname$shrext'
+    ;;
+  openbsd*)
+    library_names_spec='$libname$shrext$versuffix'
+    ;;
+  os2*)
+    libname_spec='$name'
+    shrext=.dll
+    library_names_spec='$libname.a'
+    ;;
+  osf3* | osf4* | osf5*)
+    library_names_spec='$libname$shrext'
+    ;;
+  rdos*)
+    ;;
+  solaris*)
+    library_names_spec='$libname$shrext'
+    ;;
+  sunos4*)
+    library_names_spec='$libname$shrext$versuffix'
+    ;;
+  sysv4 | sysv4.3*)
+    library_names_spec='$libname$shrext'
+    ;;
+  sysv4*MP*)
+    library_names_spec='$libname$shrext'
+    ;;
+  sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+    library_names_spec='$libname$shrext'
+    ;;
+  uts4*)
+    library_names_spec='$libname$shrext'
+    ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
index e416ceb..c354836 100644 (file)
@@ -641,6 +641,11 @@ if test "$have_pthread" = yes; then
    AC_DEFINE(HAVE_PTHREAD, ,[Define if we have pthread.])
 fi
 
+#
+# See which thread system we have
+# FIXME: Thus duplicates the above check.
+#
+gl_LOCK
 
 # Solaris needs -lsocket and -lnsl. Unisys system includes
 # gethostbyname in libsocket but needs libnsl for socket.
index 096a674..50357d1 100644 (file)
@@ -181,7 +181,7 @@ static int quick_test;
 static int faked_rng;
 
 /* This is the lock we use to protect all pool operations.  */
-static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER;
+static ath_mutex_t pool_lock;
 
 /* This is a helper for assert calls.  These calls are used to assert
    that functions are called in a locked state.  It is not meant to be
@@ -191,7 +191,7 @@ static int pool_is_locked;
 
 /* This is the lock we use to protect the buffer used by the nonce
    generation.  */
-static ath_mutex_t nonce_buffer_lock = ATH_MUTEX_INITIALIZER;
+static ath_mutex_t nonce_buffer_lock;
 
 
 /* We keep some counters in this structure for the sake of the
index d8bfe4c..9422e85 100644 (file)
@@ -28,6 +28,7 @@
    sensitive data.
  */
 
+#error This dameon needs to be fixed due to the ath changes
 
 #include <config.h>
 #include <stdio.h>
index 307d2b2..e0ae968 100644 (file)
@@ -72,7 +72,7 @@
    integer variable is only used to check the locking state; that is,
    it is not meant to be thread-safe but merely as a failsafe feature
    to assert proper locking.  */
-static ath_mutex_t fips_rng_lock = ATH_MUTEX_INITIALIZER;
+static ath_mutex_t fips_rng_lock;
 static int fips_rng_is_locked;
 
 
index 94525ef..2c93e11 100644 (file)
@@ -1,3 +1,25 @@
+2011-09-16  Werner Koch  <wk@g10code.com>
+
+       Change ATH code and turn the thread initialization callbacks in
+       the API into dummy functions.
+
+       * global.c (global_init): Call _gcry_pimegen_init.
+
+       * gcrypt.h.in (GCRY_THREAD_OPTI ON_VERSION): Bump to 1.
+       (GCRY_THREAD_OPTION_PTH_IMPL): Simplify.
+       (GCRY_THREAD_OPTION_PTHREAD_IMPL): Simplify.
+
+       * ath.c (ath_read, ath_write): Remove.  They are only used in the
+       optional random-daemon.
+       (ath_select, ath_waitpid, ath_accept, ath_connect, ath_sendmsg)
+       (ath_recvmsg): Remove.  They are not used.
+       * ath.h: Remove prototypes and corresponding structure fields.
+
+2011-03-11  Werner Koch  <wk@g10code.com>
+
+       * ath.c (mutex_init): Rename second arg to FORCE and invert
+       logic.  Change all callers.
+
 2011-09-15  Werner Koch  <wk@g10code.com>
 
        * gcrypt.h.in (enum gcry_thread_option): Remove deprecated enum.
index 656ed89..4834a52 100644 (file)
--- a/src/ath.c
+++ b/src/ath.c
-/* ath.c - Thread-safeness library.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
-
-   This file is part of Libgcrypt.
-
-   Libgcrypt is free software; you can redistribute it and/or modify
-   it under the terms of the GNU Lesser General Public License as
-   published by the Free Software Foundation; either version 2.1 of
-   the License, or (at your option) any later version.
-
-   Libgcrypt 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 Lesser General Public
-   License along with Libgcrypt; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+/* ath.c - A Thread-safeness library.
+ *  Copyright (C) 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
-#include <assert.h>  /* Right: We need to use assert and not gcry_assert.  */
+#include <stdlib.h>
 #include <unistd.h>
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#else
-# include <sys/time.h>
-#endif
-#include <sys/types.h>
-#ifndef _WIN32
-#include <sys/wait.h>
-#endif
 #include <errno.h>
+#if USE_POSIX_THREADS_WEAK
+# include <pthread.h>
+#endif
 
 #include "ath.h"
 
 
 \f
-/* The interface table.  */
-static struct ath_ops ops;
-
-/* True if we should use the external callbacks.  */
-static int ops_set;
-
+/* On an ELF system it is easy to use pthreads using weak references.
+   Take care not to test the address of a weak referenced function we
+   actually use; some GCC versions have a bug were &foo != NULL is
+   always evaluated to true in PIC mode.  USING_PTHREAD_AS_DEFAULT is
+   used by ath_install to detect the default usage of pthread.  */
+#if USE_POSIX_THREADS_WEAK
+# pragma weak pthread_cancel
+# pragma weak pthread_mutex_init
+# pragma weak pthread_mutex_lock
+# pragma weak pthread_mutex_unlock
+# pragma weak pthread_mutex_destroy
+#endif
 
-/* For the dummy interface.  */
-#define MUTEX_UNLOCKED ((ath_mutex_t) 0)
-#define MUTEX_LOCKED   ((ath_mutex_t) 1)
-#define MUTEX_DESTROYED        ((ath_mutex_t) 2)
+/* For the dummy interface.  The MUTEX_NOTINIT value is used to check
+   that a mutex has been initialized.  Because its value is there is
+   no need to explicit initialized a mutex variable because it is
+   anyway static and we store a pointer to allocated memory there
+   after initialization.  The same thing works with other thread
+   models. */
+#define MUTEX_NOTINIT  ((ath_mutex_t) 0)
+#define MUTEX_UNLOCKED ((ath_mutex_t) 1)
+#define MUTEX_LOCKED   ((ath_mutex_t) 2)
+#define MUTEX_DESTROYED        ((ath_mutex_t) 3)
 
 
 /* Return the thread type from the option field. */
 #define GET_OPTION(a)    ((a) & 0xff)
-/* Return the version number from the option field.  */
-#define GET_VERSION(a)   (((a) >> 8)& 0xff)
 
 
 \f
-/* The lock we take while checking for lazy lock initialization.  */
-static ath_mutex_t check_init_lock = ATH_MUTEX_INITIALIZER;
+enum ath_thread_model {
+  ath_model_undefined = 0,
+  ath_model_none,          /* No thread support.  */
+  ath_model_pthreads_weak, /* POSIX threads using weak symbols.  */
+  ath_model_pthreads,      /* POSIX threads directly linked.  */
+  ath_model_w32            /* Microsoft Windows threads.  */
+};
+
+
+/* The thread model in use.  */
+static enum ath_thread_model thread_model;
+
+
+/* Initialize the ath subsystem.  This is called as part of the
+   Libgcrypt initialization.  It's purpose is to initialize the
+   locking system.  It returns 0 on sucess or an ERRNO value on error.
+   In the latter case it is not defined whether ERRNO was changed.
 
+   Note: This should be called as early as possible because it is not
+   always possible to detect the thread model to use while already
+   running multi threaded.  */
 int
 ath_init (void)
 {
   int err = 0;
 
-  if (ops_set)
-    {
-      if (ops.init)
-       err = (*ops.init) ();
-      if (err)
-       return err;
-      err = (*ops.mutex_init) (&check_init_lock);
-    }
-  return err;
-}
+  if (thread_model)
+    return 0; /* Already initialized - no error.  */
 
-
-/* Initialize the locking library.  Returns 0 if the operation was
-   successful, EINVAL if the operation table was invalid and EBUSY if
-   we already were initialized.  */
-gpg_err_code_t
-ath_install (struct ath_ops *ath_ops, int check_only)
-{
-  if (check_only)
+  if (0)
+    ;
+#if USE_POSIX_THREADS_WEAK
+  else if (pthread_cancel)
     {
-      unsigned int option = 0;
-
-      /* Check if the requested thread option is compatible to the
-        thread option we are already committed to.  */
-      if (ath_ops)
-       option = ath_ops->option;
-
-      if (!ops_set && GET_OPTION (option))
-       return GPG_ERR_NOT_SUPPORTED;
-
-      if (GET_OPTION (ops.option) == ATH_THREAD_OPTION_USER
-         || GET_OPTION (option) == ATH_THREAD_OPTION_USER
-         || GET_OPTION (ops.option) != GET_OPTION (option)
-          || GET_VERSION (ops.option) != GET_VERSION (option))
-       return GPG_ERR_NOT_SUPPORTED;
-
-      return 0;
+      thread_model = ath_model_pthreads_weak;
     }
-
-  if (ath_ops)
+#endif
+  else
     {
-      /* It is convenient to not require DESTROY.  */
-      if (!ath_ops->mutex_init || !ath_ops->mutex_lock
-         || !ath_ops->mutex_unlock)
-       return GPG_ERR_INV_ARG;
-
-      ops = *ath_ops;
-      ops_set = 1;
+      /* Assume a single threaded application.  */
+      thread_model = ath_model_none;
     }
-  else
-    ops_set = 0;
-
-  return 0;
-}
-
-
-static int
-mutex_init (ath_mutex_t *lock, int just_check)
-{
-  int err = 0;
 
-  if (just_check)
-    (*ops.mutex_lock) (&check_init_lock);
-  if (*lock == ATH_MUTEX_INITIALIZER || !just_check)
-    err = (*ops.mutex_init) (lock);
-  if (just_check)
-    (*ops.mutex_unlock) (&check_init_lock);
   return err;
 }
 
 
-int
-ath_mutex_init (ath_mutex_t *lock)
+/* Return the used thread model as string for display purposes an if
+   R_MODEL is not null store its internal number at R_MODEL.  */
+const char *
+ath_get_model (int *r_model)
 {
-  if (ops_set)
-    return mutex_init (lock, 0);
-
-#ifndef NDEBUG
-  *lock = MUTEX_UNLOCKED;
-#endif
-  return 0;
-}
-
-
-int
-ath_mutex_destroy (ath_mutex_t *lock)
-{
-  if (ops_set)
+  if (r_model)
+    *r_model = thread_model;
+  switch (thread_model)
     {
-      if (!ops.mutex_destroy)
-       return 0;
-
-      (*ops.mutex_lock) (&check_init_lock);
-      if (*lock == ATH_MUTEX_INITIALIZER)
-       {
-         (*ops.mutex_unlock) (&check_init_lock);
-         return 0;
-       }
-      (*ops.mutex_unlock) (&check_init_lock);
-      return (*ops.mutex_destroy) (lock);
+    case ath_model_undefined:     return "undefined";
+    case ath_model_none:          return "none";
+    case ath_model_pthreads_weak: return "pthread(weak)";
+    case ath_model_pthreads:      return "pthread";
+    case ath_model_w32:           return "w32";
+    default:                      return "?";
     }
-
-#ifndef NDEBUG
-  assert (*lock == MUTEX_UNLOCKED);
-
-  *lock = MUTEX_DESTROYED;
-#endif
-  return 0;
 }
 
 
-int
-ath_mutex_lock (ath_mutex_t *lock)
+/* This function was used in old Libgcrypt versions (via
+   GCRYCTL_SET_THREAD_CBS) to register the thread callback functions.
+   It is not anymore required.  However to allow existing code to
+   continue to work, we keep this function and check that no user
+   defined callbacks are used and that the requested thread system
+   matches the one Libgcrypt is using.  */
+gpg_err_code_t
+ath_install (struct ath_ops *ath_ops)
 {
-  if (ops_set)
+  unsigned int thread_option;
+
+  /* Check if the requested thread option is compatible to the
+     thread option we are already committed to.  */
+  thread_option = ath_ops? GET_OPTION (ath_ops->option) : 0;
+
+  /* Return an error if the requested thread model does not match the
+     configured one.  */
+  if (0)
+    ;
+#if USE_POSIX_THREADS_WEAK
+  else if (thread_model == ath_model_pthreads_weak)
     {
-      int ret = mutex_init (lock, 1);
-      if (ret)
-       return ret;
-      return (*ops.mutex_lock) (lock);
+      if (thread_option == ATH_THREAD_OPTION_PTHREAD)
+        return 0; /* Okay - compatible.  */
     }
+#endif /*USE_POSIX_THREADS_WEAK*/
+  else if (thread_option == ATH_THREAD_OPTION_DEFAULT)
+    return 0; /* No thread support requested.  */
 
-#ifndef NDEBUG
-  assert (*lock == MUTEX_UNLOCKED);
-
-  *lock = MUTEX_LOCKED;
-#endif
-  return 0;
+  return GPG_ERR_NOT_SUPPORTED;
 }
 
 
+/* Initialize a new mutex.  This function returns 0 on success or an
+   system error code (i.e. an ERRNO value).  ERRNO may or may not be
+   changed on error.  */
 int
-ath_mutex_unlock (ath_mutex_t *lock)
+ath_mutex_init (ath_mutex_t *lock)
 {
-  if (ops_set)
+  int err;
+
+  switch (thread_model)
     {
-      int ret = mutex_init (lock, 1);
-      if (ret)
-       return ret;
-      return (*ops.mutex_unlock) (lock);
+    case ath_model_none:
+      *lock = MUTEX_UNLOCKED;
+      err = 0;
+      break;
+
+#if USE_POSIX_THREADS_WEAK
+    case ath_model_pthreads_weak:
+      {
+        pthread_mutex_t *plck;
+
+        plck = malloc (sizeof *plck);
+        if (!plck)
+          err = errno? errno : ENOMEM;
+        else
+          {
+            err = pthread_mutex_init (plck, NULL);
+            if (err)
+              free (plck);
+            else
+              *lock = (void*)plck;
+          }
+      }
+      break;
+#endif /*USE_POSIX_THREADS_WEAK*/
+
+    default:
+      err = EINVAL;
+      break;
     }
 
-#ifndef NDEBUG
-  assert (*lock == MUTEX_LOCKED);
-
-  *lock = MUTEX_UNLOCKED;
-#endif
-  return 0;
+  return err;
 }
 
 
-ssize_t
-ath_read (int fd, void *buf, size_t nbytes)
+/* Destroy a mutex.  This function is a NOP if LOCK is NULL.  If the
+   mutex is still locked it can't be destroyed and the function
+   returns EBUSY.  ERRNO may or may not be changed on error.  */
+int
+ath_mutex_destroy (ath_mutex_t *lock)
 {
-  if (ops_set && ops.read)
-    return (*ops.read) (fd, buf, nbytes);
-  else
-    return read (fd, buf, nbytes);
-}
-
+  int err;
 
-ssize_t
-ath_write (int fd, const void *buf, size_t nbytes)
-{
-  if (ops_set && ops.write)
-    return (*ops.write) (fd, buf, nbytes);
-  else
-    return write (fd, buf, nbytes);
-}
-
-
-ssize_t
-#ifdef _WIN32
-ath_select (int nfd, void *rset, void *wset, void *eset,
-           struct timeval *timeout)
-#else
-ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
-           struct timeval *timeout)
-#endif
-{
-  if (ops_set && ops.select)
-    return (*ops.select) (nfd, rset, wset, eset, timeout);
-  else
-#ifdef _WIN32
-    return -1;
-#else
-    return select (nfd, rset, wset, eset, timeout);
-#endif
-}
+  if (!*lock)
+    return 0;
 
+  switch (thread_model)
+    {
+    case ath_model_none:
+      if (*lock != MUTEX_UNLOCKED)
+        err = EBUSY;
+      else
+        {
+          *lock = MUTEX_DESTROYED;
+          err = 0;
+        }
+      break;
+
+#if USE_POSIX_THREADS_WEAK
+    case ath_model_pthreads_weak:
+      {
+        pthread_mutex_t *plck = (pthread_mutex_t*)lock;
+
+        err = pthread_mutex_destroy (plck);
+        if (!err)
+          {
+            free (plck);
+            lock = NULL;
+          }
+      }
+      break;
+#endif /*USE_POSIX_THREADS_WEAK*/
+
+    default:
+      err = EINVAL;
+      break;
+    }
 
-ssize_t
-ath_waitpid (pid_t pid, int *status, int options)
-{
-  if (ops_set && ops.waitpid)
-    return (*ops.waitpid) (pid, status, options);
-  else
-#ifdef _WIN32
-    return -1;
-#else
-    return waitpid (pid, status, options);
-#endif
+  return err;
 }
 
 
+/* Lock the mutex LOCK.  On success the function returns 0; on error
+   an error code.  ERRNO may or may not be changed on error.  */
 int
-#ifdef _WIN32
-ath_accept (int s, void *addr, int *length_ptr)
-#else
-ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
-#endif
+ath_mutex_lock (ath_mutex_t *lock)
 {
-  if (ops_set && ops.accept)
-    return (*ops.accept) (s, addr, length_ptr);
-  else
-#ifdef _WIN32
-    return -1;
-#else
-    return accept (s, addr, length_ptr);
-#endif
-}
+  int err;
 
+  switch (thread_model)
+    {
+    case ath_model_none:
+      if (*lock == MUTEX_NOTINIT)
+        err = EINVAL;
+      else if (*lock == MUTEX_UNLOCKED)
+        {
+          *lock = MUTEX_LOCKED;
+          err = 0;
+        }
+      else
+        err = EDEADLK;
+      break;
+
+#if USE_POSIX_THREADS_WEAK
+    case ath_model_pthreads_weak:
+      err = pthread_mutex_lock ((pthread_mutex_t*)lock);
+      break;
+#endif /*USE_POSIX_THREADS_WEAK*/
+
+    default:
+      err = EINVAL;
+      break;
+    }
 
-int
-#ifdef _WIN32
-ath_connect (int s, void *addr, int length)
-#else
-ath_connect (int s, struct sockaddr *addr, socklen_t length)
-#endif
-{
-  if (ops_set && ops.connect)
-    return (*ops.connect) (s, addr, length);
-  else
-#ifdef _WIN32
-    return -1;
-#else
-    return connect (s, addr, length);
-#endif
+  return err;
 }
 
-
+/* Unlock the mutex LOCK.  On success the function returns 0; on error
+   an error code.  ERRNO may or may not be changed on error.  */
 int
-#ifdef _WIN32
-ath_sendmsg (int s, const void *msg, int flags)
-#else
-ath_sendmsg (int s, const struct msghdr *msg, int flags)
-#endif
+ath_mutex_unlock (ath_mutex_t *lock)
 {
-  if (ops_set && ops.sendmsg)
-    return (*ops.sendmsg) (s, msg, flags);
-  else
-#ifdef _WIN32
-    return -1;
-#else
-    return sendmsg (s, msg, flags);
-#endif
-}
+  int err;
 
+  switch (thread_model)
+    {
+    case ath_model_none:
+      if (*lock == MUTEX_NOTINIT)
+        err = EINVAL;
+      else if (*lock == MUTEX_LOCKED)
+        {
+          *lock = MUTEX_UNLOCKED;
+          err = 0;
+        }
+      else
+        err = EPERM;
+      break;
+
+#if USE_POSIX_THREADS_WEAK
+    case ath_model_pthreads_weak:
+      err = pthread_mutex_unlock ((pthread_mutex_t*)lock);
+      break;
+#endif /*USE_POSIX_THREADS_WEAK*/
+
+    default:
+      err = EINVAL;
+      break;
+    }
 
-int
-#ifdef _WIN32
-ath_recvmsg (int s, void *msg, int flags)
-#else
-ath_recvmsg (int s, struct msghdr *msg, int flags)
-#endif
-{
-  if (ops_set && ops.recvmsg)
-    return (*ops.recvmsg) (s, msg, flags);
-  else
-#ifdef _WIN32
-    return -1;
-#else
-    return recvmsg (s, msg, flags);
-#endif
+  return err;
 }
index 8769551..6ffa928 100644 (file)
--- a/src/ath.h
+++ b/src/ath.h
@@ -1,22 +1,21 @@
 /* ath.h - Thread-safeness library.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
-
-   This file is part of Libgcrypt.
-
-   Libgcrypt is free software; you can redistribute it and/or modify
-   it under the terms of the GNU Lesser General Public License as
-   published by the Free Software Foundation; either version 2.1 of
-   the License, or (at your option) any later version.
-
-   Libgcrypt 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 Lesser General Public
-   License along with Libgcrypt; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+ * Copyright (C) 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
 
 #ifndef ATH_H
 #define ATH_H
 #define _ATH_PREFIX(x) _ATH_PREFIX2(_ATH_EXT_SYM_PREFIX,x)
 #define ath_install _ATH_PREFIX(ath_install)
 #define ath_init _ATH_PREFIX(ath_init)
+#define ath_get_model _ATH_PREFIX(ath_get_model)
 #define ath_mutex_init _ATH_PREFIX(ath_mutex_init)
 #define ath_mutex_destroy _ATH_PREFIX(ath_mutex_destroy)
 #define ath_mutex_lock _ATH_PREFIX(ath_mutex_lock)
 #define ath_mutex_unlock _ATH_PREFIX(ath_mutex_unlock)
-#define ath_read _ATH_PREFIX(ath_read)
-#define ath_write _ATH_PREFIX(ath_write)
-#define ath_select _ATH_PREFIX(ath_select)
-#define ath_waitpid _ATH_PREFIX(ath_waitpid)
-#define ath_connect _ATH_PREFIX(ath_connect)
-#define ath_accept _ATH_PREFIX(ath_accept)
-#define ath_sendmsg _ATH_PREFIX(ath_sendmsg)
-#define ath_recvmsg _ATH_PREFIX(ath_recvmsg)
 #endif
 
 \f
@@ -83,65 +75,18 @@ struct ath_ops
   */
   unsigned int option;
 
-  int (*init) (void);
-  int (*mutex_init) (void **priv);
-  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);
-#ifdef _WIN32
-  ssize_t (*select) (int nfd, void *rset, void *wset, void *eset,
-                    struct timeval *timeout);
-  ssize_t (*waitpid) (pid_t pid, int *status, int options);
-  int (*accept) (int s, void  *addr, int *length_ptr);
-  int (*connect) (int s, void *addr, int length);
-  int (*sendmsg) (int s, const void *msg, int flags);
-  int (*recvmsg) (int s, void *msg, int flags);
-#else
-  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);
-  int (*accept) (int s, struct sockaddr *addr, socklen_t *length_ptr);
-  int (*connect) (int s, struct sockaddr *addr, socklen_t length);
-  int (*sendmsg) (int s, const struct msghdr *msg, int flags);
-  int (*recvmsg) (int s, struct msghdr *msg, int flags);
-#endif
 };
 
-gpg_err_code_t ath_install (struct ath_ops *ath_ops, int check_only);
+gpg_err_code_t ath_install (struct ath_ops *ath_ops);
 int ath_init (void);
-
+const char *ath_get_model (int *r_model);
 
 /* Functions for mutual exclusion.  */
 typedef void *ath_mutex_t;
-#define ATH_MUTEX_INITIALIZER 0
 
 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);
-#ifdef _WIN32
-ssize_t ath_select (int nfd, void *rset, void *wset, void *eset,
-                   struct timeval *timeout);
-ssize_t ath_waitpid (pid_t pid, int *status, int options);
-int ath_accept (int s, void *addr, int *length_ptr);
-int ath_connect (int s, void *addr, int length);
-int ath_sendmsg (int s, const void *msg, int flags);
-int ath_recvmsg (int s, void *msg, int flags);
-#else
-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);
-int ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr);
-int ath_connect (int s, struct sockaddr *addr, socklen_t length);
-int ath_sendmsg (int s, const struct msghdr *msg, int flags);
-int ath_recvmsg (int s, struct msghdr *msg, int flags);
-#endif
-
 #endif /* ATH_H */
index 8bc45e7..a3445eb 100644 (file)
@@ -69,7 +69,7 @@ static int enforced_fips_mode;
 static int inactive_fips_mode;
 
 /* This is the lock we use to protect the FSM.  */
-static ath_mutex_t fsm_lock = ATH_MUTEX_INITIALIZER;
+static ath_mutex_t fsm_lock;
 
 /* The current state of the FSM.  The whole state machinery is only
    used while in fips mode. Change this only while holding fsm_lock. */
index a55d3d6..f468ac4 100644 (file)
@@ -167,6 +167,7 @@ const char *_gcry_mpi_get_hw_config (void);
 #endif
 
 /*-- primegen.c --*/
+gcry_err_code_t _gcry_primegen_init (void);
 gcry_mpi_t _gcry_generate_secret_prime (unsigned int nbits,
                                  gcry_random_level_t random_level,
                                  int (*extra_check)(void*, gcry_mpi_t),
index b34ff08..8e23ec4 100644 (file)
@@ -174,6 +174,10 @@ gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err);
 gcry_err_code_t gcry_error_from_errno (int err);
 
 \f
+/* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore
+   used.  However we keep it to allow for some source code
+   compatibility if used in the standard way.  */
+
 /* Constants defining the thread model to use.  Used with the OPTION
    field of the struct gcry_thread_cbs.  */
 #define GCRY_THREAD_OPTION_DEFAULT  0
@@ -183,7 +187,7 @@ gcry_err_code_t gcry_error_from_errno (int err);
 
 /* The version number encoded in the OPTION field of the struct
    gcry_thread_cbs.  */
-#define GCRY_THREAD_OPTION_VERSION  0
+#define GCRY_THREAD_OPTION_VERSION  1
 
 /* Wrapper for struct ath_ops.  */
 struct gcry_thread_cbs
@@ -191,144 +195,18 @@ struct gcry_thread_cbs
   /* The OPTION field encodes the thread model and the version number
      of this structure.
        Bits  7 - 0  are used for the thread model
-       Bits 15 - 8  are used for the version number.
-  */
+       Bits 15 - 8  are used for the version number.  */
   unsigned int option;
+} _GCRY_ATTR_INTERNAL;
 
-  int (*init) (void);
-  int (*mutex_init) (void **priv);
-  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);
-#ifdef _WIN32
-  ssize_t (*select) (int nfd, void *rset, void *wset, void *eset,
-                    struct timeval *timeout);
-  ssize_t (*waitpid) (pid_t pid, int *status, int options);
-  int (*accept) (int s, void  *addr, int *length_ptr);
-  int (*connect) (int s, void *addr, gcry_socklen_t length);
-  int (*sendmsg) (int s, const void *msg, int flags);
-  int (*recvmsg) (int s, void *msg, int flags);
-#else
-  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);
-  int (*accept) (int s, struct sockaddr *addr, gcry_socklen_t *length_ptr);
-  int (*connect) (int s, struct sockaddr *addr, gcry_socklen_t length);
-  int (*sendmsg) (int s, const struct msghdr *msg, int flags);
-  int (*recvmsg) (int s, struct msghdr *msg, int flags);
-#endif
-};
-
-#ifdef _WIN32
-# define _GCRY_THREAD_OPTION_PTH_IMPL_NET                                    \
-static ssize_t gcry_pth_select (int nfd, void *rset, void *wset,             \
-                               void *eset, struct timeval *timeout)          \
-  { return pth_select (nfd, rset, wset, eset, timeout); }                    \
-static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options)        \
-  { return pth_waitpid (pid, status, options); }                             \
-static int gcry_pth_accept (int s, void *addr,                                \
-                           gcry_socklen_t *length_ptr)                       \
-  { return pth_accept (s, addr, length_ptr); }                               \
-static int gcry_pth_connect (int s, void *addr,                                      \
-                            gcry_socklen_t length)                           \
-  { return pth_connect (s, addr, length); }
-#else /*!_WIN32*/
-# define _GCRY_THREAD_OPTION_PTH_IMPL_NET                                    \
-static ssize_t gcry_pth_select (int nfd, fd_set *rset, fd_set *wset,         \
-                               fd_set *eset, struct timeval *timeout)        \
-  { return pth_select (nfd, rset, wset, eset, timeout); }                    \
-static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options)        \
-  { return pth_waitpid (pid, status, options); }                             \
-static int gcry_pth_accept (int s, struct sockaddr *addr,                    \
-                           gcry_socklen_t *length_ptr)                       \
-  { return pth_accept (s, addr, length_ptr); }                               \
-static int gcry_pth_connect (int s, struct sockaddr *addr,                   \
-                            gcry_socklen_t length)                           \
-  { return pth_connect (s, addr, length); }
-#endif /*!_WIN32*/
-
+#define GCRY_THREAD_OPTION_PTH_IMPL                                     \
+  static struct gcry_thread_cbs gcry_threads_pth = {                    \
+    (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8))}
 
+#define GCRY_THREAD_OPTION_PTHREAD_IMPL                                 \
+  static struct gcry_thread_cbs gcry_threads_pthread = {                \
+    (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))}
 
-#define GCRY_THREAD_OPTION_PTH_IMPL                                          \
-static int gcry_pth_init (void)                                                      \
-{ return (pth_init () == FALSE) ? errno : 0; }                               \
-static int gcry_pth_mutex_init (void **priv)                                 \
-{                                                                            \
-  int err = 0;                                                               \
-  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;                                                         \
-    }                                                                        \
-  return err;                                                                \
-}                                                                            \
-static int gcry_pth_mutex_destroy (void **lock)                                      \
-  { /* GNU Pth has no destructor function.  */ free (*lock); return 0; }      \
-static int gcry_pth_mutex_lock (void **lock)                                 \
-  { return ((pth_mutex_acquire (*lock, 0, NULL)) == FALSE)                   \
-      ? errno : 0; }                                                         \
-static int gcry_pth_mutex_unlock (void **lock)                               \
-  { return ((pth_mutex_release (*lock)) == FALSE)                            \
-      ? errno : 0; }                                                         \
-static ssize_t gcry_pth_read (int fd, void *buf, size_t nbytes)                      \
-  { return pth_read (fd, buf, nbytes); }                                     \
-static ssize_t gcry_pth_write (int fd, const void *buf, size_t nbytes)       \
-  { return pth_write (fd, buf, nbytes); }                                    \
-_GCRY_THREAD_OPTION_PTH_IMPL_NET                                              \
-                                                                             \
-/* Note: GNU Pth is missing pth_sendmsg and pth_recvmsg.  */                 \
-static struct gcry_thread_cbs gcry_threads_pth = {                            \
-  (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8)),               \
-  gcry_pth_init, gcry_pth_mutex_init, gcry_pth_mutex_destroy,                \
-  gcry_pth_mutex_lock, gcry_pth_mutex_unlock, gcry_pth_read, gcry_pth_write,  \
-  gcry_pth_select, gcry_pth_waitpid, gcry_pth_accept, gcry_pth_connect,       \
-  NULL, NULL }
-
-
-#define GCRY_THREAD_OPTION_PTHREAD_IMPL                                              \
-static int gcry_pthread_mutex_init (void **priv)                             \
-{                                                                            \
-  int err = 0;                                                               \
-  pthread_mutex_t *lock = (pthread_mutex_t*)malloc (sizeof (pthread_mutex_t));\
-                                                                             \
-  if (!lock)                                                                 \
-    err = ENOMEM;                                                            \
-  if (!err)                                                                  \
-    {                                                                        \
-      err = pthread_mutex_init (lock, NULL);                                 \
-      if (err)                                                               \
-       free (lock);                                                          \
-      else                                                                   \
-       *priv = lock;                                                         \
-    }                                                                        \
-  return err;                                                                \
-}                                                                            \
-static int gcry_pthread_mutex_destroy (void **lock)                          \
-  { int err = pthread_mutex_destroy ((pthread_mutex_t*)*lock);                \
-    free (*lock); return err; }                                               \
-static int gcry_pthread_mutex_lock (void **lock)                             \
-  { return pthread_mutex_lock ((pthread_mutex_t*)*lock); }                   \
-static int gcry_pthread_mutex_unlock (void **lock)                           \
-  { return pthread_mutex_unlock ((pthread_mutex_t*)*lock); }                 \
-                                                                             \
-static struct gcry_thread_cbs gcry_threads_pthread = {                       \
-  (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)),           \
-  NULL, gcry_pthread_mutex_init, gcry_pthread_mutex_destroy,                 \
-  gcry_pthread_mutex_lock, gcry_pthread_mutex_unlock,                         \
-  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
 
 \f
 /* The data object used to hold a multi precision integer.  */
index 93ff800..36d6646 100644 (file)
@@ -104,16 +104,21 @@ global_init (void)
   /* Initialize our portable thread/mutex wrapper.  */
   err = ath_init ();
   if (err)
-    goto fail;
+    {
+      err = gpg_error_from_errno (err);
+      goto fail;
+    }
 
   /* See whether the system is in FIPS mode.  This needs to come as
-     early as possible put after the ATH has been initialized.  */
+     early as possible but after ATH has been initialized.  */
   _gcry_initialize_fips_mode (force_fips_mode);
 
   /* Before we do any other initialization we need to test available
      hardware features.  */
   _gcry_detect_hw_features (disabled_hw_features);
 
+  /* Initialize the modules - this is mainly allocating some memory and
+     creating mutexes.  */
   err = _gcry_cipher_init ();
   if (err)
     goto fail;
@@ -123,6 +128,9 @@ global_init (void)
   err = _gcry_pk_init ();
   if (err)
     goto fail;
+  err = _gcry_primegen_init ();
+  if (err)
+    goto fail;
 
   return;
 
@@ -284,6 +292,7 @@ print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
 #endif
        "\n");
   fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
+  fnc (fp, "threads:%s:\n", ath_get_model (NULL));
   hwf = _gcry_get_hw_features ();
   fnc (fp, "hwflist:");
   for (i=0; hwflist[i].desc; i++)
@@ -435,8 +444,8 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
       break;
 
     case GCRYCTL_SET_THREAD_CBS:
-      err = ath_install (va_arg (arg_ptr, void *), any_init_done);
-      if (! err)
+      err = ath_install (va_arg (arg_ptr, void *));
+      if (!err)
        global_init ();
       break;