Commit 04e8e538 authored by Philippe Gerum via Xenomai's avatar Philippe Gerum via Xenomai Committed by Jan Kiszka

lib/cobalt: init: do not call pthread_atfork() from atfork() handlers

Since glibc 2.28, calling pthread_atfork() over the context of a fork
handler hangs, due to unexpected recursive locking on a common lock
both want to acquire.  To fix this, the cobalt fork handler needs to
be registered outside of the atfork handling context it installs.

At this chance, group all base inits which do not need to be
reiterated in the forkee to exclude them from the atfork context.

The problematic change was introduced between glibc-2.27.9000 and
glibc-2.28 [1]; it triggered a bug in the glibc test suite [2].

[1] git://sourceware.org/git/glibc.git, 27761a104
[2] git://sourceware.org/git/glibc.git, 669ff911e
Signed-off-by: Philippe Gerum's avatarPhilippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka's avatarJan Kiszka <jan.kiszka@siemens.com>
parent 598c367a
......@@ -184,20 +184,26 @@ static void low_init(void)
cobalt_ticks_init(f->clock_freq);
}
static int cobalt_init_2(void);
static void cobalt_fork_handler(void)
{
cobalt_unmap_umm();
cobalt_clear_tsd();
cobalt_print_init_atfork();
if (cobalt_init())
if (cobalt_init_2())
exit(EXIT_FAILURE);
}
static void __cobalt_init(void)
static inline void commit_stack_memory(void)
{
struct sigaction sa;
char stk[PTHREAD_STACK_MIN / 2];
cobalt_commit_memory(stk);
}
low_init();
static void cobalt_init_1(void)
{
struct sigaction sa;
sa.sa_sigaction = cobalt_sigdebug_handler;
sigemptyset(&sa.sa_mask);
......@@ -228,20 +234,9 @@ static void __cobalt_init(void)
" sizeof(cobalt_sem_shadow): %Zd!",
sizeof(sem_t),
sizeof(struct cobalt_sem_shadow));
cobalt_mutex_init();
cobalt_sched_init();
cobalt_thread_init();
cobalt_print_init();
}
static inline void commit_stack_memory(void)
{
char stk[PTHREAD_STACK_MIN / 2];
cobalt_commit_memory(stk);
}
int cobalt_init(void)
static int cobalt_init_2(void)
{
pthread_t ptid = pthread_self();
struct sched_param parm;
......@@ -249,7 +244,12 @@ int cobalt_init(void)
commit_stack_memory(); /* We only need this for the main thread */
cobalt_default_condattr_init();
__cobalt_init();
low_init();
cobalt_mutex_init();
cobalt_sched_init();
cobalt_thread_init();
cobalt_print_init();
if (__cobalt_control_bind)
return 0;
......@@ -288,12 +288,19 @@ int cobalt_init(void)
return 0;
}
int cobalt_init(void)
{
cobalt_init_1();
return cobalt_init_2();
}
static int get_int_arg(const char *name, const char *arg,
int *valp, int min)
{
int value, ret;
char *p;
errno = 0;
value = (int)strtol(arg, &p, 10);
if (errno || *p || value < min) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment