/* Test-in-thread wrapper function for the test driver.
Copyright (C) 2025 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library 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.
The GNU C Library 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 the GNU C Library; if not, see
.
The support_test_in_thread_wrapper function defined here gets called from
within support_test_main, but needs to be compiled separately. This is
done in order to avoid linking every test (irrespective of necessity)
against pthread_create etc., which has implications for Hurd and
statically linked tests. */
#include
#include
#include
#include
struct test_thread_args
{
int argc;
char **argv;
const struct test_config *config;
int ret;
};
static void *
test_thread (void *closure)
{
struct test_thread_args *args = closure;
if (args->config->test_function != NULL)
args->ret = args->config->test_function ();
else if (args->config->test_function_argv != NULL)
args->ret = args->config->test_function_argv (args->argc, args->argv);
else
{
printf ("error: no test function defined\n");
exit (1);
}
return NULL;
}
static pthread_barrier_t barrier;
static void *
empty_thread (void *closure)
{
/* Make sure that the alternate thread waits (and exists) till the main
thread finishes running the test. */
xpthread_barrier_wait (&barrier);
return NULL;
}
int
support_test_in_thread_wrapper (int argc, char **argv,
const struct test_config *config)
{
pthread_t thread;
struct test_thread_args closure = {.argc = argc,
.argv = argv,
.config = config};
if (config->test_in_thread == TEST_THREAD_MAIN)
{
xpthread_barrier_init (&barrier, NULL, 2);
thread = xpthread_create (NULL, empty_thread, NULL);
/* Run the test in the main thread. */
test_thread (&closure);
/* Signal to the alternate thread that it can return. */
xpthread_barrier_wait (&barrier);
xpthread_join (thread);
}
else /* config->test_in_thread == TEST_THREAD_WORKER. */
{
/* Run the test in an alternate thread. */
thread = xpthread_create (NULL, test_thread, &closure);
xpthread_join (thread);
}
return closure.ret;
}