diff --git a/tests/Makefile.am b/tests/Makefile.am index be04df3..a8327d6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,44 +1,49 @@ # Makefile.am for libgpg-error/tests. # Copyright (C) 2003 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ## Process this file with automake to produce Makefile.in if HAVE_W32CE_SYSTEM extra_includes = -idirafter $(top_builddir)/src/gpg-extra else extra_includes = endif EXTRA_DIST = t-argparse.conf etc/t-argparse.conf gpg_error_lib = ../src/libgpg-error.la TESTS = t-version t-strerror t-syserror t-lock t-printf t-poll t-b64 \ t-argparse t-logging t-stringutils t-malloc +if HAVE_W32_SYSTEM +else +TESTS += t-lock-single-posix +endif + AM_CPPFLAGS = -I$(top_builddir)/src $(extra_includes) AM_LDFLAGS = -no-install LDADD = $(gpg_error_lib) @LDADD_FOR_TESTS_KLUDGE@ noinst_PROGRAMS = $(TESTS) noinst_HEADERS = t-common.h t_lock_LDADD = $(LDADD) $(LIBMULTITHREAD) t_poll_LDADD = $(LDADD) $(LIBMULTITHREAD) diff --git a/tests/t-lock-single-posix.c b/tests/t-lock-single-posix.c new file mode 100644 index 0000000..e3432b1 --- /dev/null +++ b/tests/t-lock-single-posix.c @@ -0,0 +1,165 @@ +/* t-lock-single-posix.c - Check the lock functions with single thread + * Copyright (C) 2021 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 . + */ + +#if HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#define PGM "t-lock-single" + +#include "t-common.h" + +GPGRT_LOCK_DEFINE (the_lock); + +static int locking_used; + +#ifdef USE_POSIX_THREADS_FROM_LIBC +#include + +static void * +thread_func (void *arg) +{ + (void)arg; + return NULL; +} +#endif + +static void +run_test (void) +{ + gpg_err_code_t rc; + + rc = gpgrt_lock_lock (&the_lock); + if (rc) + fail ("gpgrt_lock_lock failed at %d: %s", __LINE__, gpg_strerror (rc)); + + rc = gpgrt_lock_unlock (&the_lock); + if (rc) + fail ("gpgrt_lock_unlock failed at %d: %s", __LINE__,gpg_strerror (rc)); + + if (locking_used) + /*It was incremented, even with single thread. */ + fail ("Single thread situation is not correctly handled\n"); + +#ifdef USE_POSIX_THREADS_FROM_LIBC + /* + * With !USE_POSIX_THREADS_FROM_LIBC, it is determined at link time. + * + * With USE_POSIX_THREADS_FROM_LIBC, it is determined at runtime, + * and the condition is changed when an application actually uses + * thread. + */ + { + pthread_t rthread; + pthread_create (&rthread, NULL, thread_func, NULL); + + rc = gpgrt_lock_lock (&the_lock); + if (rc) + fail ("gpgrt_lock_lock failed at %d: %s", __LINE__, gpg_strerror (rc)); + + rc = gpgrt_lock_unlock (&the_lock); + if (rc) + fail ("gpgrt_lock_unlock failed at %d: %s", __LINE__,gpg_strerror (rc)); + + pthread_join (rthread, NULL); + + if (!locking_used) + /*It was *NOT* incremented, even with multiple threads. */ + fail ("Multiple threads situation is not correctly handled\n"); + } +#endif +} + + +static void +syscall_clam_pre (void) +{ + if (debug) + show ("syscall pre called\n"); + locking_used++; +} + +static void +syscall_clam_post (void) +{ + if (debug) + show ("syscall post called\n"); +} + +int +main (int argc, char **argv) +{ + int last_argc = -1; + int rc; + + if (argc) + { + argc--; argv++; + } + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--help")) + { + puts ( +"usage: ./t-lock-single [options]\n" +"\n" +"Options:\n" +" --verbose Show what is going on\n" +" --debug Flyswatter\n" +); + exit (0); + } + if (!strcmp (*argv, "--verbose")) + { + verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--debug")) + { + verbose = debug = 1; + argc--; argv++; + } + } + + if (!gpg_error_check_version (GPG_ERROR_VERSION)) + { + die ("gpg_error_check_version returned an error"); + errorcount++; + } + + gpgrt_set_syscall_clamp (syscall_clam_pre, syscall_clam_post); + + rc = gpgrt_lock_init (&the_lock); + if (rc) + fail ("gpgrt_lock_init failed at %d: %s", __LINE__, gpg_strerror (rc)); + + run_test (); + + gpgrt_lock_destroy (&the_lock); + + return errorcount ? 1 : 0; +}