Merge branch 'fix-560' into 'develop'

Fix #560

Closes #560

See merge request embeddable-common-lisp/ecl!185
This commit is contained in:
Daniel Kochmański 2020-02-17 21:32:06 +00:00
commit f0d8f8dcf7
3 changed files with 30 additions and 11 deletions

View file

@ -287,9 +287,11 @@ si_clear_gfun_hash(cl_object what)
for (list = mp_all_processes(); !Null(list); list = ECL_CONS_CDR(list)) {
cl_object process = ECL_CONS_CAR(list);
struct cl_env_struct *env = process->process.env;
if (the_env != env) {
ecl_cache_remove_one(env->method_cache, what);
ecl_cache_remove_one(env->slot_cache, what);
if (the_env != env && env) {
if (env->method_cache)
ecl_cache_remove_one(env->method_cache, what);
if (env->slot_cache)
ecl_cache_remove_one(env->slot_cache, what);
}
}
#endif

View file

@ -179,7 +179,9 @@ ecl_init_env(cl_env_ptr env)
env->method_cache = ecl_make_cache(64, 4096);
env->slot_cache = ecl_make_cache(3, 4096);
env->interrupt_struct = ecl_alloc(sizeof(*env->interrupt_struct));
env->interrupt_struct->pending_interrupt = ECL_NIL;
env->interrupt_struct->signal_queue_spinlock = ECL_NIL;
{
int size = ecl_option_values[ECL_OPT_SIGNAL_QUEUE_SIZE];
env->interrupt_struct->signal_queue = cl_make_list(1, ecl_make_fixnum(size));
@ -224,6 +226,13 @@ _ecl_alloc_env(cl_env_ptr parent)
* Allocates the lisp environment for a thread. Depending on which
* mechanism we use for detecting delayed signals, we may allocate
* the environment using mmap or the garbage collector.
*
* Note that at this point we are not allocating any other memory
* which is stored via a pointer in the environment. If we would do
* that, an unlucky interrupt by the gc before the allocated
* environment is registered in cl_core.processes could lead to
* memory being freed because the gc is not aware of the pointer to
* the allocated memory in the environment.
*/
cl_env_ptr output;
#if defined(ECL_USE_MPROTECT)
@ -249,10 +258,6 @@ _ecl_alloc_env(cl_env_ptr parent)
}
# endif
#endif
if (!ecl_option_values[ECL_OPT_BOOTED])
output->interrupt_struct = ecl_alloc_unprotected(sizeof(*output->interrupt_struct));
else
output->interrupt_struct = ecl_alloc(sizeof(*output->interrupt_struct));
{
size_t bytes = cl_core.default_sigmask_bytes;
if (bytes == 0) {
@ -266,13 +271,13 @@ _ecl_alloc_env(cl_env_ptr parent)
output->default_sigmask = cl_core.default_sigmask;
}
}
output->method_cache = output->slot_cache = NULL;
output->interrupt_struct = NULL;
/*
* An uninitialized environment _always_ disables interrupts. They
* are activated later on by the thread entry point or init_unixint().
*/
output->disable_interrupts = 1;
output->interrupt_struct->pending_interrupt = ECL_NIL;
output->interrupt_struct->signal_queue_spinlock = ECL_NIL;
return output;
}

View file

@ -403,14 +403,20 @@ ecl_import_current_thread(cl_object name, cl_object bindings)
process->process.phase = ECL_PROCESS_BOOTING;
process->process.thread = current;
/* Immediately list the process such that its environment is
* marked by the gc when its contents are allocated */
ecl_list_process(process);
/* Now we can safely allocate memory for the environment contents
* and store pointers to it in the environment */
ecl_init_env(env);
env->cleanup = registered;
env->bindings_array = process->process.initial_bindings;
env->thread_local_bindings_size = env->bindings_array->vector.dim;
env->thread_local_bindings = env->bindings_array->vector.self.t;
ecl_enable_interrupts_env(env);
ecl_list_process(process);
/* Activate the barrier so that processes can immediately start waiting. */
mp_barrier_unblock(1, process->process.exit_barrier);
process->process.phase = ECL_PROCESS_ACTIVE;
@ -544,14 +550,20 @@ mp_process_enable(cl_object process)
process->process.parent = mp_current_process();
process->process.trap_fpe_bits =
process->process.parent->process.env->trap_fpe_bits;
ecl_list_process(process);
/* Link environment and process together */
process_env = _ecl_alloc_env(the_env);
process_env->own_process = process;
process->process.env = process_env;
/* Immediately list the process such that its environment is
* marked by the gc when its contents are allocated */
ecl_list_process(process);
/* Now we can safely allocate memory for the environment contents
* and store pointers to it in the environment */
ecl_init_env(process_env);
process_env->trap_fpe_bits = process->process.trap_fpe_bits;
process_env->bindings_array = process->process.initial_bindings;
process_env->thread_local_bindings_size =