threading: fix race condition in stacks_scanner

The garbage collector can call stacks_scanner in a thread before
    pthread_setspecific, leading to a wrong error message. The
    solution is simply not to mark the environment, if
    pthread_setspecific has not yet been called.
This commit is contained in:
Marius Gerbershagen 2018-02-20 21:40:04 +01:00
parent f9630fa8b3
commit a8d7305fb6
3 changed files with 14 additions and 1 deletions

View file

@ -1353,7 +1353,7 @@ ecl_mark_env(struct cl_env_struct *env)
static void
stacks_scanner()
{
cl_env_ptr the_env = ecl_process_env();
cl_env_ptr the_env = ecl_process_env_unsafe();
cl_object l;
l = cl_core.libraries;
if (l) {

View file

@ -43,6 +43,16 @@ static pthread_key_t cl_env_key;
extern void ecl_init_env(struct cl_env_struct *env);
#if !defined(WITH___THREAD)
cl_env_ptr
ecl_process_env_unsafe(void)
{
#ifdef ECL_WINDOWS_THREADS
return TlsGetValue(cl_env_key);
#else
return pthread_getspecific(cl_env_key);
#endif
}
cl_env_ptr
ecl_process_env(void)
{

View file

@ -161,14 +161,17 @@ struct ecl_interrupt_struct {
# ifdef WITH___THREAD
# define cl_env (*cl_env_p)
# define ecl_process_env() cl_env_p
# define ecl_process_env_unsafe() cl_env_p
extern __thread cl_env_ptr cl_env_p;
# else
# define cl_env (*ecl_process_env())
extern ECL_API cl_env_ptr ecl_process_env(void) __attribute__((const));
extern ECL_API cl_env_ptr ecl_process_env_unsafe(void) __attribute__((const));
# endif
#else
# define cl_env (*cl_env_p)
# define ecl_process_env() cl_env_p
# define ecl_process_env_unsafe() cl_env_p
extern ECL_API cl_env_ptr cl_env_p;
#endif