wingo pushed a commit to branch wip-whippet
in repository guile.

commit 17ca7a928e32dfa67aa986b55d214614c835927c
Author: Andy Wingo <wi...@pobox.com>
AuthorDate: Sun May 4 09:12:52 2025 +0200

    Don't run finalizers until Guile is initialized
    
    Prevents a problem where with-exception-handler isn't defined yet by the
    time the first finalizer gets kicked off (it's a file port, probably one
    that is closed already...)
    
    * libguile/finalizers.h:
    * libguile/init.c (scm_i_init_guile):
    * libguile/finalizers.c (queue_finalizer_async): Mark maybe-unused.
    (scm_init_finalizers): Rework to only enable notification when Guile is
    finished initializing.
---
 libguile/finalizers.c | 31 ++++++++++++++++---------------
 libguile/finalizers.h |  1 -
 libguile/init.c       |  3 +--
 3 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/libguile/finalizers.c b/libguile/finalizers.c
index 45b063f30..07335a970 100644
--- a/libguile/finalizers.c
+++ b/libguile/finalizers.c
@@ -267,6 +267,8 @@ run_finalizers_async_thunk (void)
  * scm_run_finalizers() at the next SCM_TICK in this thread.
  */
 static void
+queue_finalizer_async (struct gc_heap *heap, size_t count) SCM_UNUSED;
+static void
 queue_finalizer_async (struct gc_heap *heap, size_t count)
 {
   scm_thread *t = SCM_I_CURRENT_THREAD;
@@ -520,18 +522,6 @@ scm_register_finalizers (void)
                             NULL);
 }
 
-void
-scm_init_finalizers (void)
-{
-  /* When the async is to run, the cdr of the pair gets set to the
-     asyncs queue of the current thread.  */
-  run_finalizers_subr = scm_c_make_gsubr ("%run-finalizers", 0, 0, 0,
-                                          run_finalizers_async_thunk);
-
-  if (automatic_finalization_p)
-    gc_set_finalizer_callback (the_gc_heap, queue_finalizer_async);
-}
-
 static void
 scm_init_finalizers_module (void)
 {
@@ -541,10 +531,21 @@ scm_init_finalizers_module (void)
 }
 
 void
-scm_init_finalizer_thread (void)
+scm_init_finalizers (void)
 {
-#if SCM_USE_PTHREAD_THREADS
+  /* When the async is to run, the cdr of the pair gets set to the
+     asyncs queue of the current thread.  */
+  run_finalizers_subr = scm_c_make_gsubr ("%run-finalizers", 0, 0, 0,
+                                          run_finalizers_async_thunk);
+
   if (automatic_finalization_p)
-    gc_set_finalizer_callback (the_gc_heap, spawn_finalizer_thread);
+    {
+#if SCM_USE_PTHREAD_THREADS
+      gc_set_finalizer_callback (the_gc_heap, spawn_finalizer_thread);
+#else
+      gc_set_finalizer_callback (the_gc_heap, queue_finalizer_async);
 #endif
+    }
+
+  scm_run_finalizers ();
 }
diff --git a/libguile/finalizers.h b/libguile/finalizers.h
index 0265eb23d..9fab7b66d 100644
--- a/libguile/finalizers.h
+++ b/libguile/finalizers.h
@@ -51,6 +51,5 @@ SCM_INTERNAL int scm_i_print_finalizer (SCM exp, SCM port,
                                         scm_print_state *pstate SCM_UNUSED);
 SCM_INTERNAL void scm_register_finalizers (void);
 SCM_INTERNAL void scm_init_finalizers (void);
-SCM_INTERNAL void scm_init_finalizer_thread (void);
 
 #endif  /* SCM_FINALIZERS_H */
diff --git a/libguile/init.c b/libguile/init.c
index 12a0c6671..32ff25cc6 100644
--- a/libguile/init.c
+++ b/libguile/init.c
@@ -390,7 +390,6 @@ scm_i_init_guile (struct gc_stack_addr base)
   scm_init_dynwind ();            /* requires smob_prehistory */
   scm_init_eq ();
   scm_init_error ();
-  scm_init_finalizers ();
   scm_init_fluids ();
   scm_init_control ();            /* requires fluids */
   scm_init_feature ();
@@ -505,5 +504,5 @@ scm_i_init_guile (struct gc_stack_addr base)
   scm_init_threads_default_dynamic_state ();
 
   /* Finally, cause finalizers to run in a separate thread.  */
-  scm_init_finalizer_thread ();
+  scm_init_finalizers ();
 }

Reply via email to