Merge branch 'fix-560' into 'develop'
Fix #560 Closes #560 See merge request embeddable-common-lisp/ecl!185
This commit is contained in:
commit
f0d8f8dcf7
3 changed files with 30 additions and 11 deletions
|
|
@ -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
|
||||
|
|
|
|||
17
src/c/main.d
17
src/c/main.d
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue