aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am44
-rw-r--r--src/err-codes.h.in6
-rw-r--r--src/gen-posix-lock-obj.c95
-rw-r--r--src/gen-w32-lock-obj.c55
-rw-r--r--src/gpg-error.def.in6
-rw-r--r--src/gpg-error.h.in35
-rw-r--r--src/lock.h24
-rw-r--r--src/mkheader.c18
-rw-r--r--src/posix-lock-obj.h32
-rw-r--r--src/posix-lock.c213
-rw-r--r--src/posix-thread.c63
-rw-r--r--src/thread.h24
-rw-r--r--src/version.c4
-rw-r--r--src/w32-lock-obj-pub.in44
-rw-r--r--src/w32-lock-obj.h38
-rw-r--r--src/w32-lock.c119
-rw-r--r--src/w32-thread.c44
17 files changed, 843 insertions, 21 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 74d89be..51b2ea9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -30,7 +30,15 @@ extra_cppflags =
endif
localedir = $(datadir)/locale
+
bin_PROGRAMS = gpg-error
+
+if HAVE_W32_SYSTEM
+noinst_PROGRAMS = gen-w32-lock-obj
+else
+noinst_PROGRAMS = gen-posix-lock-obj
+endif
+
lib_LTLIBRARIES = libgpg-error.la
include_HEADERS = gpg-error.h
bin_SCRIPTS = gpg-error-config
@@ -42,7 +50,8 @@ EXTRA_DIST = mkstrtable.awk err-sources.h.in err-codes.h.in \
mkerrcodes.awk mkerrcodes1.awk mkerrcodes2.awk mkerrcodes.c \
mkheader.c gpg-error.h.in mkw32errmap.c w32-add.h w32ce-add.h \
err-sources.h err-codes.h gpg-error-config.in gpg-error.m4 \
- gpg-error.def.in versioninfo.rc.in
+ gpg-error.def.in versioninfo.rc.in \
+ w32-lock-obj-pub.in
BUILT_SOURCES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h \
err-sources-sym.h err-codes-sym.h errnos-sym.h gpg-error.h \
@@ -53,11 +62,10 @@ tmp_files = _mkerrcodes.h _gpg-error.def.h mkw32errmap.tab.h mkw32errmap.map.c
CLEANFILES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h \
gpg-error.h mkerrcodes mkerrcodes.h gpg-error.def mkw32errmap.tab.h \
mkw32errmap.map.c err-sources-sym.h err-codes-sym.h errnos-sym.h \
- gpg-extra/errno.h mkheader $(tmp_files)
+ gpg-extra/errno.h mkheader $(tmp_files) posix-lock-obj-pub.in
if HAVE_W32_SYSTEM
-arch_sources = w32-gettext.c
-
+arch_sources = w32-gettext.c w32-lock.c w32-lock-obj.h w32-thread.c
RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS) $(CPPFLAGS)
LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE)
@@ -82,7 +90,7 @@ libgpg_error_la_DEPENDENCIES = $(gpg_error_res) gpg-error.def
intllibs =
else
-arch_sources =
+arch_sources = posix-lock.c posix-lock-obj.h posix-thread.c
gpg_error_res =
no_undefined =
export_symbols =
@@ -98,17 +106,22 @@ libgpg_error_la_LDFLAGS = -version-info \
@LIBGPG_ERROR_LT_CURRENT@:@LIBGPG_ERROR_LT_REVISION@:@LIBGPG_ERROR_LT_AGE@ \
$(no_undefined) $(export_symbols)
-parts_of_gpg_error_h = \
- gpg-error.h.in \
- err-sources.h.in \
- err-codes.h.in \
- errnos.in \
- w32-add.h \
- w32ce-add.h
+parts_of_gpg_error_h = \
+ gpg-error.h.in \
+ err-sources.h.in \
+ err-codes.h.in \
+ errnos.in \
+ w32-add.h \
+ w32ce-add.h \
+ w32-lock-obj-pub.in
+
+if ! HAVE_W32_SYSTEM
+parts_of_gpg_error_h += posix-lock-obj-pub.in
+endif
libgpg_error_la_SOURCES = gpg-error.h gettext.h $(arch_sources) \
- init.c init.h version.c \
+ init.c init.h version.c lock.h thread.h \
strsource.c strerror.c code-to-errno.c code-from-errno.c
# Note that RCCOMPILE needs the same defines as ..._la_CPPFLAGS but
@@ -195,9 +208,14 @@ errnos-sym.h: Makefile mkstrtable.awk errnos.in
-v prefix=GPG_ERR_ -v namespace=errnos_ \
$(srcdir)/errnos.in >$@
+
mkheader: mkheader.c Makefile
$(CC_FOR_BUILD) -g -O0 -I. -I$(srcdir) -o $@ $(srcdir)/mkheader.c
+
+posix-lock-obj-pub.in: Makefile gen-posix-lock-obj posix-lock-obj.h
+ ./gen-posix-lock-obj >$@
+
# We also depend on versioninfo.rc because that is build by
# config.status and thus has up-to-date version numbers.
gpg-error.h: Makefile mkheader $(parts_of_gpg_error_h) versioninfo.rc
diff --git a/src/err-codes.h.in b/src/err-codes.h.in
index 4ecc24e..c912bcd 100644
--- a/src/err-codes.h.in
+++ b/src/err-codes.h.in
@@ -247,7 +247,11 @@
212 GPG_ERR_SEXP_ODD_HEX_NUMBERS Odd hexadecimal numbers in S-expression
213 GPG_ERR_SEXP_BAD_OCT_CHAR Bad octal character in S-expression
-# 214 to 254 are free to be used. 255 and 256 are RFU.
+# 214 to 253 are free to be used.
+
+254 GPG_ERR_INV_LOCK_OBJ Invalid lock object
+
+# 255 and 256 are RFU.
# Error codes pertaining to the Assuan IPC interface
257 GPG_ERR_ASS_GENERAL General IPC error
diff --git a/src/gen-posix-lock-obj.c b/src/gen-posix-lock-obj.c
new file mode 100644
index 0000000..b641fd0
--- /dev/null
+++ b/src/gen-posix-lock-obj.c
@@ -0,0 +1,95 @@
+/* gen-posix-lock-obj.c - Build tool to construct the lock object.
+ Copyright (C) 2014 g10 Code GmbH
+
+ This file is part of libgpg-error.
+
+ libgpg-error 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.
+
+ libgpg-error 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/>.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_W32_SYSTEM
+# error This module may not be build for Windows.
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+
+#include "posix-lock-obj.h"
+
+#define PGM "gen-posix-lock-obj"
+
+/* Check that configure did its job. */
+#if SIZEOF_PTHREAD_MUTEX_T < 4
+# error sizeof pthread_mutex_t is not known.
+#endif
+
+static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+
+
+int
+main (void)
+{
+ unsigned char *p;
+ int i;
+ struct {
+ pthread_mutex_t mtx;
+ long vers;
+ } dummyobj;
+
+ if (sizeof mtx != SIZEOF_PTHREAD_MUTEX_T)
+ {
+ fprintf (stderr, PGM ": pthread_mutex_t mismatch\n");
+ exit (1);
+ }
+
+ if (sizeof (dummyobj) != sizeof (_gpgrt_lock_t))
+ {
+ fprintf (stderr, PGM ": internal and external lock object mismatch\n");
+ exit (1);
+ }
+
+ /* To force a probably suitable alignment of the structure we use a
+ union and include a long and a pointer to a long. */
+ printf ("## File created by " PGM " - DO NOT EDIT\n"
+ "## To be included by mkheader into gpg-error.h\n"
+ "\n"
+ "typedef union\n"
+ "{\n"
+ " struct {\n"
+ " volatile char _priv[%d];\n"
+ " long _vers;\n"
+ " } d;\n"
+ " long _x_align;\n"
+ " long *_xp_align;\n"
+ "} gpgrt_lock_t;\n"
+ "\n"
+ "#define GPGRT_LOCK_INITIALIZER {{{",
+ SIZEOF_PTHREAD_MUTEX_T);
+ p = (unsigned char *)&mtx;
+ for (i=0; i < sizeof mtx; i++)
+ {
+ if (i && !(i % 8))
+ printf (" \\\n%*s", 34, "");
+ printf ("%u", p[i]);
+ if (i < sizeof mtx - 1)
+ putchar (',');
+ }
+ printf ("},%d}}\n", LOCK_ABI_VERSION);
+
+ return 0;
+}
diff --git a/src/gen-w32-lock-obj.c b/src/gen-w32-lock-obj.c
new file mode 100644
index 0000000..9e49d1e
--- /dev/null
+++ b/src/gen-w32-lock-obj.c
@@ -0,0 +1,55 @@
+/* gen-w32-lock-obj.c - Build tool to get the size of the lock object.
+ Copyright (C) 2014 g10 Code GmbH
+
+ This file is part of libgpg-error.
+
+ libgpg-error 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.
+
+ libgpg-error 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/>.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_W32_SYSTEM
+# error This module may only be build for Windows.
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <windows.h>
+
+#include "w32-lock-obj.h"
+
+
+int
+main (void)
+{
+ _gpgrt_lock_t lk;
+ unsigned char *p;
+ int i;
+
+ printf ("sizeof CRITICAL_SECTION = %u\n", (int)sizeof (CRITICAL_SECTION));
+ printf ("sizeof _gpgrt_lock_t = %u\n", (int)sizeof lk);
+
+ memset (&lk, 0, sizeof lk);
+ lk.vers = LOCK_ABI_VERSION;
+ lk.started = -1;
+ printf ("#define GPGRT_LOCK_INITIALIZER {");
+ p = (unsigned char *)&lk;
+ for (i=0; i < sizeof lk - 1; i++)
+ printf ("%u,", p[i]);
+ printf ("%u}\n", p[sizeof(lk)-1]);
+
+ return 0;
+}
diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in
index 62e0681..2ea482a 100644
--- a/src/gpg-error.def.in
+++ b/src/gpg-error.def.in
@@ -28,3 +28,9 @@ EXPORTS
#endif
gpg_err_deinit @18
gpg_error_check_version @19
+
+ gpgrt_lock_init @20
+ gpgrt_lock_lock @21
+ gpgrt_lock_unlock @22
+ gpgrt_lock_destroy @23
+ gpgrt_yield @24
diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in
index a2fb044..adb796b 100644
--- a/src/gpg-error.h.in
+++ b/src/gpg-error.h.in
@@ -66,7 +66,10 @@ extern "C" {
GPG_ERR_ENABLE_GETTEXT_MACROS: Define to provide macros to map the
internal gettext API to standard names. This has only an effect on
- Windows platforms. */
+ Windows platforms.
+
+ In addition to the error codes, Libgpg-error also provides a set of
+ functions used by most GnuPG components. */
/* The error source type gpg_err_source_t.
@@ -279,9 +282,35 @@ gpg_error_from_syserror (void)
return gpg_error (gpg_err_code_from_syserror ());
}
+
+
+/* Lock functions. */
+
+@include:lock-obj@
+
+#define GPGRT_LOCK_DEFINE(name) \
+ static gpgrt_lock_t name = GPGRT_LOCK_INITIALIZER
+
+
+gpg_err_code_t gpgrt_lock_init (gpgrt_lock_t *lockhd);
+gpg_err_code_t gpgrt_lock_lock (gpgrt_lock_t *lockhd);
+gpg_err_code_t gpgrt_lock_unlock (gpgrt_lock_t *lockhd);
+gpg_err_code_t gpgrt_lock_destroy (gpgrt_lock_t *lockhd);
+
+
+
+/* Thread functions. */
+
+gpg_err_code_t gpgrt_yield (void);
+
+
+
+
+/* Estream */
+
+
+
#ifdef __cplusplus
}
#endif
-
-
#endif /* GPG_ERROR_H */
diff --git a/src/lock.h b/src/lock.h
new file mode 100644
index 0000000..b60f2c2
--- /dev/null
+++ b/src/lock.h
@@ -0,0 +1,24 @@
+/* lock.h - Declarations for *-lock.c
+ Copyright (C) 2014 g10 Code GmbH
+
+ This file is part of libgpg-error.
+
+ libgpg-error 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.
+
+ libgpg-error 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 LOCK_H
+#define LOCK_H
+
+
+#endif /*LOCK_H*/
diff --git a/src/mkheader.c b/src/mkheader.c
index eea7914..e7db729 100644
--- a/src/mkheader.c
+++ b/src/mkheader.c
@@ -132,7 +132,8 @@ write_errnos_in (char *line)
is not further expanded. It may have comments indicated by a
double hash mark at the begin of a line. OUTF is called for each
read line and passed a buffer with the content of line sans line
- line endings. */
+ line endings. If NAME is prefixed with "./" it is included from
+ the current directory and not from the source directory. */
static void
include_file (const char *fname, int lnr, const char *name, void (*outf)(char*))
{
@@ -147,7 +148,11 @@ include_file (const char *fname, int lnr, const char *name, void (*outf)(char*))
fputs (PGM ": out of core\n", stderr);
exit (1);
}
- strcpy (incfname, srcdir);
+
+ if (*name == '.' && name[1] == '/')
+ *incfname = 0;
+ else
+ strcpy (incfname, srcdir);
strcat (incfname, name);
fp = fopen (incfname, "r");
@@ -242,6 +247,15 @@ write_special (const char *fname, int lnr, const char *tag)
include_file (fname, lnr, "w32ce-add.h", write_line);
}
}
+ else if (!strcmp (tag, "include:lock-obj"))
+ {
+ if (!strcmp (host_os, "mingw32"))
+ {
+ include_file (fname, lnr, "w32-lock-obj-pub.in", write_line);
+ }
+ else
+ include_file (fname, lnr, "./posix-lock-obj-pub.in", write_line);
+ }
else
return 0; /* Unknown tag. */
diff --git a/src/posix-lock-obj.h b/src/posix-lock-obj.h
new file mode 100644
index 0000000..a5a9ee7
--- /dev/null
+++ b/src/posix-lock-obj.h
@@ -0,0 +1,32 @@
+/* posic-lock-obj.h - Declaration of the POSIX lock object
+ Copyright (C) 2014 g10 Code GmbH
+
+ This file is part of libgpg-error.
+
+ libgpg-error 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.
+
+ libgpg-error 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 POSIX_LOCK_OBJ_H
+#define POSIX_LOCK_OBJ_H
+
+#define LOCK_ABI_VERSION 1
+
+typedef struct
+{
+ pthread_mutex_t mtx;
+ long vers;
+} _gpgrt_lock_t;
+
+
+#endif /*POSIX_LOCK_OBJ_H*/
diff --git a/src/posix-lock.c b/src/posix-lock.c
new file mode 100644
index 0000000..46e3a84
--- /dev/null
+++ b/src/posix-lock.c
@@ -0,0 +1,213 @@
+/* posix-lock.c - GPGRT lock functions for POSIX systems
+ Copyright (C) 2005-2009 Free Software Foundation, Inc.
+ Copyright (C) 2014 g10 Code GmbH
+
+ This file is part of libgpg-error.
+
+ libgpg-error 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.
+
+ libgpg-error 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/>.
+
+ Parts of the code, in particular use_pthreads_p, are based on code
+ from gettext, written by Bruno Haible <[email protected]>, 2005.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_W32_SYSTEM
+# error This module may not be build for Windows.
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#if USE_POSIX_THREADS
+# include <pthread.h>
+#endif
+
+#include "gpg-error.h"
+#include "lock.h"
+#include "posix-lock-obj.h"
+
+
+#if USE_POSIX_THREADS
+# if USE_POSIX_THREADS_WEAK
+ /* On ELF systems 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. */
+# pragma weak pthread_cancel
+# pragma weak pthread_mutex_init
+# pragma weak pthread_mutex_lock
+# pragma weak pthread_mutex_unlock
+# pragma weak pthread_mutex_destroy
+# if ! PTHREAD_IN_USE_DETECTION_HARD
+# define use_pthread_p() (!!pthread_cancel)
+# endif
+# else /*!USE_POSIX_THREADS_WEAK*/
+# if ! PTHREAD_IN_USE_DETECTION_HARD
+# define use_pthread_p() (1)
+# endif
+# endif /*!USE_POSIX_THREADS_WEAK*/
+# if PTHREAD_IN_USE_DETECTION_HARD
+/* The function to be executed by a dummy thread. */
+static void *
+dummy_thread_func (void *arg)
+{
+ return arg;
+}
+
+static int
+use_pthread_p (void)
+{
+ static int tested;
+ static int result; /* 1: linked with -lpthread, 0: only with libc */
+
+ if (!tested)
+ {
+ pthread_t thread;
+
+ if (pthread_create (&thread, NULL, dummy_thread_func, NULL))
+ result = 0; /* Thread creation failed. */
+ else
+ {
+ /* Thread creation works. */
+ void *retval;
+ if (pthread_join (thread, &retval) != 0)
+ abort ();
+ result = 1;
+ }
+ tested = 1;
+ }
+ return result;
+}
+#endif /*PTHREAD_IN_USE_DETECTION_HARD*/
+#endif /*USE_POSIX_THREADS*/
+
+
+
+static _gpgrt_lock_t *
+get_lock_object (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = (_gpgrt_lock_t*)lockhd;
+
+ if (lock->vers != LOCK_ABI_VERSION)
+ abort ();
+ if (sizeof (gpgrt_lock_t) < sizeof (_gpgrt_lock_t))
+ abort ();
+
+ return lock;
+}
+
+
+gpg_err_code_t
+gpgrt_lock_init (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = get_lock_object (lockhd);
+ int rc;
+
+#if USE_POSIX_THREADS
+ if (use_pthread_p())
+ {
+ rc = pthread_mutex_init (&lock->mtx, NULL);
+ if (rc)
+ rc = gpg_err_code_from_errno (rc);
+ }
+ else
+ rc = 0; /* Threads are not used. */
+#else /* Unknown thread system. */
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+#endif /* Unknown thread system. */
+
+ return rc;
+}
+
+
+gpg_err_code_t
+gpgrt_lock_lock (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = get_lock_object (lockhd);
+ int rc;
+
+#if USE_POSIX_THREADS
+ if (use_pthread_p())
+ {
+ rc = pthread_mutex_lock (&lock->mtx);
+ if (rc)
+ rc = gpg_err_code_from_errno (rc);
+ }
+ else
+ rc = 0; /* Threads are not used. */
+#else /* Unknown thread system. */
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+#endif /* Unknown thread system. */
+
+ return rc;
+}
+
+
+gpg_err_code_t
+gpgrt_lock_unlock (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = get_lock_object (lockhd);
+ int rc;
+
+#if USE_POSIX_THREADS
+ if (use_pthread_p())
+ {
+ rc = pthread_mutex_unlock (&lock->mtx);
+ if (rc)
+ rc = gpg_err_code_from_errno (rc);
+ }
+ else
+ rc = 0; /* Threads are not used. */
+#else /* Unknown thread system. */
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+#endif /* Unknown thread system. */
+
+ return rc;
+}
+
+
+/* Note: Use this function only if no other thread holds or waits for
+ this lock. */
+gpg_err_code_t
+gpgrt_lock_destroy (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = get_lock_object (lockhd);
+ int rc;
+
+#if USE_POSIX_THREADS
+ if (use_pthread_p())
+ {
+ rc = pthread_mutex_destroy (&lock->mtx);
+ if (rc)
+ rc = gpg_err_code_from_errno (rc);
+ else
+ {
+ /* Re-init the the mutex so that it can be re-used. */
+ gpgrt_lock_t tmp = GPGRT_LOCK_INITIALIZER;
+ memcpy (lockhd, &tmp, sizeof tmp);
+ }
+ }
+ else
+ rc = 0; /* Threads are not used. */
+#else /* Unknown thread system. */
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+#endif /* Unknown thread system. */
+
+ return rc;
+}
diff --git a/src/posix-thread.c b/src/posix-thread.c
new file mode 100644
index 0000000..a739e40
--- /dev/null
+++ b/src/posix-thread.c
@@ -0,0 +1,63 @@
+/* posix-thread.c - GPGRT thread functions for POSIX systems
+ Copyright (C) 2014 g10 Code GmbH
+
+ This file is part of libgpg-error.
+
+ libgpg-error 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.
+
+ libgpg-error 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/>.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_W32_SYSTEM
+# error This module may not be build for Windows.
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h> /* Get posix option macros. */
+
+#if USE_POSIX_THREADS
+# ifdef _POSIX_PRIORITY_SCHEDULING
+# include <sched.h>
+# endif
+#elif USE_SOLARIS_THREADS
+# include <thread.h>
+#endif
+
+#include "gpg-error.h"
+
+#include "thread.h"
+
+
+gpg_err_code_t
+gpgrt_yield (void)
+{
+#if USE_POSIX_THREADS
+# ifdef _POSIX_PRIORITY_SCHEDULING
+ sched_yield ();
+# else
+ return GPG_ERR_NOT_SUPPORTED;
+# endif
+#elif USE_SOLARIS_THREADS
+ thr_yield ();
+#else
+ return GPG_ERR_NOT_SUPPORTED;
+#endif
+
+ return 0;
+}
diff --git a/src/thread.h b/src/thread.h
new file mode 100644
index 0000000..0b2cf04
--- /dev/null
+++ b/src/thread.h
@@ -0,0 +1,24 @@
+/* thread.h - Declarations for *-thread.c
+ Copyright (C) 2014 g10 Code GmbH
+
+ This file is part of libgpg-error.
+
+ libgpg-error 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.
+
+ libgpg-error 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 THREAD_H
+#define THREAD_H
+
+
+#endif /*THREAD_H*/
diff --git a/src/version.c b/src/version.c
index 36e2d58..5b40537 100644
--- a/src/version.c
+++ b/src/version.c
@@ -1,5 +1,5 @@
/* version.c - Version checking
- * Copyright (C) 2001, 2002, 2012, 2013 g10 Code GmbH
+ * Copyright (C) 2001, 2002, 2012, 2013, 2014 g10 Code GmbH
*
* This file is part of libgpg-error.
*
@@ -39,7 +39,7 @@ cright_blurb (void)
static const char blurb[] =
"\n\n"
"This is Libgpg-error " PACKAGE_VERSION " - An error code library\n"
- "Copyright 2003, 2004, 2010, 2013 g10 Code GmbH\n"
+ "Copyright 2003, 2004, 2010, 2013, 2014 g10 Code GmbH\n"
"\n"
"(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n"
"\n\n";
diff --git a/src/w32-lock-obj-pub.in b/src/w32-lock-obj-pub.in
new file mode 100644
index 0000000..2f3f911
--- /dev/null
+++ b/src/w32-lock-obj-pub.in
@@ -0,0 +1,44 @@
+## w32-lock-obj-pub.in - Include fragment for gpg-error.h -*- c-*-
+## Copyright (C) 2014 g10 Code GmbH
+##
+## This file is free software; as a special exception the author gives
+## unlimited permission to copy and/or distribute it, with or without
+## modifications, as long as this notice is preserved.
+##
+## This file is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+## implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+##
+##
+## This file defines the public version of the lock object for 32 bit
+## Windows. The actual used version is in w32-lock-obj.h. This file
+## is inserted into gpg-error.h by mkheader.c. The tool
+## gen-w32-lock-obj.c has been used to construct it.
+
+#ifdef _WIN64
+
+#pragma pack(push, 8)
+typedef struct
+{
+ volatile char priv[56];
+} gpgrt_lock_t;
+#pragma pack(pop)
+
+#define GPGRT_LOCK_INITIALIZER {1,0,0,0,0,0,0,0,255,255,255,255, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0,0,0,0,0}
+
+#else
+
+#pragma pack(push, 8)
+typedef struct
+{
+ volatile char priv[36];
+} gpgrt_lock_t;
+#pragma pack(pop)
+
+#define GPGRT_LOCK_INITIALIZER {1,0,0,0,0,0,0,0,255,255,255,255, \
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+ 0,0,0,0,0,0,0,0}
+#endif
diff --git a/src/w32-lock-obj.h b/src/w32-lock-obj.h
new file mode 100644
index 0000000..ef53546
--- /dev/null
+++ b/src/w32-lock-obj.h
@@ -0,0 +1,38 @@
+/* w32-lock-obj.h - Declaration of the Windows lock object
+ Copyright (C) 2014 g10 Code GmbH
+
+ This file is part of libgpg-error.
+
+ libgpg-error 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.
+
+ libgpg-error 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 W32_LOCK_OBJ_H
+#define W32_LOCK_OBJ_H
+
+#define LOCK_ABI_VERSION 1
+
+/* The real definition of our lock object. The public definition is
+ named gpgrt_lock_t and hides this internal structure. */
+#pragma pack(push, 8)
+typedef struct
+{
+ long vers;
+ volatile long initdone;
+ volatile long started;
+ CRITICAL_SECTION csec;
+} _gpgrt_lock_t;
+#pragma pack(pop)
+
+
+#endif /*W32_LOCK_OBJ_H*/
diff --git a/src/w32-lock.c b/src/w32-lock.c
new file mode 100644
index 0000000..0ad9409
--- /dev/null
+++ b/src/w32-lock.c
@@ -0,0 +1,119 @@
+/* w32-lock.c - GPGRT lock functions for Windows
+ Copyright (C) 2014 g10 Code GmbH
+
+ This file is part of libgpg-error.
+
+ libgpg-error 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.
+
+ libgpg-error 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/>.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_W32_SYSTEM
+# error This module may only be build for Windows.
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <gpg-error.h>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include "lock.h"
+#include "w32-lock-obj.h"
+
+
+static _gpgrt_lock_t *
+get_lock_object (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = (_gpgrt_lock_t*)lockhd;
+
+ if (lock->vers != LOCK_ABI_VERSION)
+ abort ();
+
+ return lock;
+}
+
+
+gpg_err_code_t
+gpgrt_lock_init (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = get_lock_object (lockhd);
+
+ if (sizeof (gpgrt_lock_t) < sizeof (_gpgrt_lock_t))
+ abort ();
+ InitializeCriticalSection (&lock->csec);
+ lock->initdone = 1;
+}
+
+
+gpg_err_code_t
+gpgrt_lock_lock (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = get_lock_object (lockhd);
+
+ if (!lock->initdone)
+ {
+ if (!InterlockedIncrement (&lock->started))
+ {
+ /* The new value of started is 0. Because the initial value
+ if the variable was -1 we known that this thread is the
+ first who needs this lock. Thus we initialize now. All
+ other threads won't get 0 back from InterlockedIncrement
+ and thus fall into the wait loop below. We ignore that
+ STARTED may in theory overflow if this thread starves for
+ too long. */
+ gpgrt_lock_init (lockhd);
+ }
+ else
+ {
+ while (!lock->initdone)
+ Sleep (0);
+ }
+ }
+
+ EnterCriticalSection (&lock->csec);
+ return 0;
+}
+
+
+gpg_err_code_t
+gpgrt_lock_unlock (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = get_lock_object (lockhd);
+
+ if (!lock->initdone)
+ return GPG_ERR_INV_LOCK_OBJ;
+ LeaveCriticalSection (&lock->csec);
+ return 0;
+}
+
+
+/* Note: Use this function only if no other thread holds or waits for
+ this lock. */
+gpg_err_code_t
+gpgrt_lock_destroy (gpgrt_lock_t *lockhd)
+{
+ _gpgrt_lock_t *lock = get_lock_object (lockhd);
+
+ if (!lock->initdone)
+ return GPG_ERR_INV_LOCK_OBJ;
+ DeleteCriticalSection (&lock->csec);
+ lock->initdone = 0;
+ lock->started = -1;
+ return 0;
+}
diff --git a/src/w32-thread.c b/src/w32-thread.c
new file mode 100644
index 0000000..f86be35
--- /dev/null
+++ b/src/w32-thread.c
@@ -0,0 +1,44 @@
+/* w32-thread.c - GPGRT thread functions for Windows
+ Copyright (C) 2014 g10 Code GmbH
+
+ This file is part of libgpg-error.
+
+ libgpg-error 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.
+
+ libgpg-error 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/>.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef HAVE_W32_SYSTEM
+# error This module may only be build for Windows.
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <gpg-error.h>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include "thread.h"
+
+
+gpg_err_code_t
+gpgrt_yield (void)
+{
+ Sleep (0);
+ return 0;
+}