From adaeaaf06cead3b996bc298f6106819b69c2dfd0 Mon Sep 17 00:00:00 2001 From: Marius Gerbershagen Date: Sun, 12 Jul 2020 17:27:47 +0200 Subject: [PATCH] gc: fix for finalizers called from non-initialized threads We can't use the standard functions like cl_list for allocating the wrapper object for the finalizer since these need a working environment for disabling interrupts. --- src/c/alloc_2.d | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/c/alloc_2.d b/src/c/alloc_2.d index 99f578315..c8f3ba616 100644 --- a/src/c/alloc_2.d +++ b/src/c/alloc_2.d @@ -1145,9 +1145,9 @@ static void wrapped_finalizer(cl_object o, cl_object finalizer); static void -deferred_finalizer(cl_object o) +deferred_finalizer(cl_object* x) { - wrapped_finalizer(cl_first(o), cl_second(o)); + wrapped_finalizer(x[0], x[1]); } void @@ -1155,7 +1155,7 @@ wrapped_finalizer(cl_object o, cl_object finalizer) { if (finalizer != ECL_NIL && finalizer != NULL) { #ifdef ECL_THREADS - const cl_env_ptr the_env = ecl_process_env(); + const cl_env_ptr the_env = ecl_process_env_unsafe(); if (!the_env || !the_env->own_process || the_env->own_process->process.phase < ECL_PROCESS_ACTIVE) @@ -1169,13 +1169,16 @@ wrapped_finalizer(cl_object o, cl_object finalizer) * the original finalizer is no more registered to o, and if o * is not anymore reachable it will be colleted. To prevent * this we need to make this object reachable again after that - * roundtrip and postpone the finalization to the next garbace - * colletion. Given that this is a rare condition one way to + * roundtrip and postpone the finalization to the next garbage + * collection. Given that this is a rare condition one way to * do that is: */ GC_finalization_proc ofn; void *odata; - GC_REGISTER_FINALIZER_NO_ORDER(cl_list(2,o,finalizer), + cl_object* wrapper = GC_MALLOC(2*sizeof(cl_object)); + wrapper[0] = o; + wrapper[1] = finalizer; + GC_REGISTER_FINALIZER_NO_ORDER(wrapper, (GC_finalization_proc)deferred_finalizer, 0, &ofn, &odata); return;