diff --git a/src/c/format.d b/src/c/format.d index b9a525dc0..6c653e92e 100644 --- a/src/c/format.d +++ b/src/c/format.d @@ -98,14 +98,14 @@ get_aux_stream(void) cl_env_ptr env = ecl_process_env(); cl_object stream; - ecl_disable_interrupts_env(env); - if (env->fmt_aux_stream == ECL_NIL) { - stream = ecl_make_string_output_stream(64, 1); - } else { - stream = env->fmt_aux_stream; - env->fmt_aux_stream = ECL_NIL; - } - ecl_enable_interrupts_env(env); + ECL_WITHOUT_INTERRUPTS_BEGIN(env) { + if (env->fmt_aux_stream == ECL_NIL) { + stream = ecl_make_string_output_stream(64, 1); + } else { + stream = env->fmt_aux_stream; + env->fmt_aux_stream = ECL_NIL; + } + } ECL_WITHOUT_INTERRUPTS_END; return stream; } diff --git a/src/c/unixint.d b/src/c/unixint.d index 127d2c87b..dd25da914 100644 --- a/src/c/unixint.d +++ b/src/c/unixint.d @@ -378,18 +378,31 @@ handle_all_queued_interrupt_safe(cl_env_ptr env) /* We have to save and later restore thread-local variables to * ensure that they don't get overwritten by the interrupting * code */ + /* INV: - Frame, Binding and IHS stack manipulations are + * interrupt safe + * - The rest of the thread local variables are + * guaranteed to be used in an interrupt safe way. This + * is not true for the compiler environment and ffi + * data, but it is unclear whether the DFFI or compiler + * are thread safe anyway. */ cl_object fun = env->function; cl_index nvalues = env->nvalues; - cl_object* values = ecl_alloc_atomic(ECL_MULTIPLE_VALUES_LIMIT*sizeof(cl_object)); + cl_object values[ECL_MULTIPLE_VALUES_LIMIT]; memcpy(values, env->values, ECL_MULTIPLE_VALUES_LIMIT*sizeof(cl_object)); cl_object big_register[3]; memcpy(big_register, env->big_register, 3*sizeof(cl_object)); + cl_object packages_to_be_created = env->packages_to_be_created; + cl_object packages_to_be_created_p = env->packages_to_be_created_p; /* We might have been interrupted while we push/pop in the * stack. Increasing env->stack_top ensures that we don't * overwrite the topmost stack value. */ env->stack_top++; + /* Finally we can handle the queued signals */ handle_all_queued(env); + /* And restore thread local variables again */ env->stack_top--; + env->packages_to_be_created_p = packages_to_be_created_p; + env->packages_to_be_created = packages_to_be_created; memcpy(env->big_register, big_register, 3*sizeof(cl_object)); memcpy(env->values, values, ECL_MULTIPLE_VALUES_LIMIT*sizeof(cl_object)); env->nvalues = nvalues; diff --git a/src/h/external.h b/src/h/external.h index 107e08a39..c1e8844bb 100755 --- a/src/h/external.h +++ b/src/h/external.h @@ -87,14 +87,16 @@ struct cl_env_struct { char *cs_barrier; /* Private variables used by different parts of ECL: */ - /* ... the reader ... */ + /* ... the reader and printer ... */ cl_object string_pool; /* ... the compiler ... */ struct cl_compiler_env *c_env; /* ... the formatter ... */ +#if !defined(ECL_CMU_FORMAT) cl_object fmt_aux_stream; +#endif /* ... arithmetics ... */ /* Note: if you change the size of these registers, change also