Commit f4c0f888 by Janne Blomqvist

Make recursion_check work for multiple threads

With multiple threads, using an unprotected static variable to check
whether recursion has occured isn't valid, as one thread might have
modified the variable, thus causing another thread to incorrectly
conclude that recursion has occured.  This patch avoids this problem
by using a thread-specific variable for the recursion check.

Regtested on x86_64-pc-linux-gnu.

libgfortran/ChangeLog:

2018-11-23  Janne Blomqvist  <jb@gcc.gnu.org>

	* runtime/error.c (MAGIC): Remove.
	(recursion_key): New variable.
	(recursion_check): Use thread-specific variable for recursion
	check if threads are active.
	(constructor_recursion_check): New function.
	(destructor_recursion_check): New funcion.

From-SVN: r266419
parent 70c70369
2018-11-23 Janne Blomqvist <jb@gcc.gnu.org>
* runtime/error.c (MAGIC): Remove.
(recursion_key): New variable.
(recursion_check): Use thread-specific variable for recursion
check if threads are active.
(constructor_recursion_check): New function.
(destructor_recursion_check): New funcion.
2018-11-22 Janne Blomqvist <jb@gcc.gnu.org> 2018-11-22 Janne Blomqvist <jb@gcc.gnu.org>
* acinclude.m4 (LIBGFOR_CHECK_ATOMIC_FETCH_ADD): Rename and test * acinclude.m4 (LIBGFOR_CHECK_ATOMIC_FETCH_ADD): Rename and test
......
...@@ -332,21 +332,50 @@ show_locus (st_parameter_common *cmp) ...@@ -332,21 +332,50 @@ show_locus (st_parameter_common *cmp)
/* recursion_check()-- It's possible for additional errors to occur /* recursion_check()-- It's possible for additional errors to occur
* during fatal error processing. We detect this condition here and * during fatal error processing. We detect this condition here and
* exit with code 4 immediately. */ * abort immediately. */
#define MAGIC 0x20DE8101 static __gthread_key_t recursion_key;
static void static void
recursion_check (void) recursion_check (void)
{ {
static int magic = 0; if (__gthread_active_p ())
{
bool* p = __gthread_getspecific (recursion_key);
if (!p)
{
p = xcalloc (1, sizeof (bool));
__gthread_setspecific (recursion_key, p);
}
if (*p)
sys_abort ();
*p = true;
}
else
{
static bool recur;
if (recur)
sys_abort ();
recur = true;
}
}
/* Don't even try to print something at this point */ #ifdef __GTHREADS
if (magic == MAGIC) static void __attribute__((constructor))
sys_abort (); constructor_recursion_check (void)
{
if (__gthread_active_p ())
__gthread_key_create (&recursion_key, &free);
}
magic = MAGIC; static void __attribute__((destructor))
destructor_recursion_check (void)
{
if (__gthread_active_p ())
__gthread_key_delete (recursion_key);
} }
#endif
#define STRERR_MAXSZ 256 #define STRERR_MAXSZ 256
......
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