/* 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;
}