diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 44 | ||||
-rw-r--r-- | src/err-codes.h.in | 6 | ||||
-rw-r--r-- | src/gen-posix-lock-obj.c | 95 | ||||
-rw-r--r-- | src/gen-w32-lock-obj.c | 55 | ||||
-rw-r--r-- | src/gpg-error.def.in | 6 | ||||
-rw-r--r-- | src/gpg-error.h.in | 35 | ||||
-rw-r--r-- | src/lock.h | 24 | ||||
-rw-r--r-- | src/mkheader.c | 18 | ||||
-rw-r--r-- | src/posix-lock-obj.h | 32 | ||||
-rw-r--r-- | src/posix-lock.c | 213 | ||||
-rw-r--r-- | src/posix-thread.c | 63 | ||||
-rw-r--r-- | src/thread.h | 24 | ||||
-rw-r--r-- | src/version.c | 4 | ||||
-rw-r--r-- | src/w32-lock-obj-pub.in | 44 | ||||
-rw-r--r-- | src/w32-lock-obj.h | 38 | ||||
-rw-r--r-- | src/w32-lock.c | 119 | ||||
-rw-r--r-- | src/w32-thread.c | 44 |
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; +} |