diff --git a/NEWS b/NEWS index 5321e953d..ff4c977de 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,5 @@ Guile NEWS --- history of user-visible changes. -Copyright (C) 1996-2024 Free Software Foundation, Inc. +Copyright (C) 1996-2025 Free Software Foundation, Inc. See the end for copying conditions. Please send Guile bug reports to bug-guile@gnu.org. @@ -80,6 +80,12 @@ every line in a file. () ** Change to allow compilation with -Werror=undef () +** 'all-threads' no longer includes the finalizer thread + () + Previously 'all-threads' would include the finalizer thread. This, + in turn, would trigger warnings from 'primitive-fork' and 'environ' + suggesting they are being called in a multi-threaded context, when in + fact user code did not create any thread. Changes in 3.0.10 (since 3.0.9) diff --git a/libguile/finalizers.c b/libguile/finalizers.c index 1370755bf..47495b595 100644 --- a/libguile/finalizers.c +++ b/libguile/finalizers.c @@ -1,4 +1,4 @@ -/* Copyright 2012-2014,2018-2020,2022 +/* Copyright 2012-2014,2018-2020,2022,2025 Free Software Foundation, Inc. This file is part of Guile. @@ -37,6 +37,7 @@ #include "gsubr.h" #include "init.h" #include "threads.h" +#include "atomics-internal.h" #include "finalizers.h" @@ -217,10 +218,14 @@ read_finalization_pipe_data (void *data) return NULL; } - + +static scm_i_pthread_t finalizer_thread; + static void* finalization_thread_proc (void *unused) { + scm_atomic_set_pointer ((void **) &finalizer_thread, + (void *) pthread_self ()); while (1) { struct finalization_pipe_data data; @@ -255,10 +260,20 @@ finalization_thread_proc (void *unused) } } +int +scm_i_is_finalizer_thread (struct scm_thread *t) +{ + scm_i_pthread_t us = + (scm_i_pthread_t) scm_atomic_ref_pointer ((void **) &finalizer_thread); + return pthread_equal (t->pthread, us); +} + static void* run_finalization_thread (void *arg) { - return scm_with_guile (finalization_thread_proc, arg); + void *res = scm_with_guile (finalization_thread_proc, arg); + scm_atomic_set_pointer ((void **) &finalizer_thread, NULL); + return res; } static void diff --git a/libguile/finalizers.h b/libguile/finalizers.h index 44bafb22e..a92a74be1 100644 --- a/libguile/finalizers.h +++ b/libguile/finalizers.h @@ -1,7 +1,7 @@ #ifndef SCM_FINALIZERS_H #define SCM_FINALIZERS_H -/* Copyright 2012, 2013, 2014, 2018 +/* Copyright 2012, 2013, 2014, 2018, 2025 Free Software Foundation, Inc. This file is part of Guile. @@ -42,6 +42,9 @@ SCM_INTERNAL void scm_i_finalizer_pre_fork (void); thread. */ SCM_INTERNAL void scm_i_register_async_gc_callback (void (*callback) (void)); +/* Return true if THREAD is the finalizer thread. */ +SCM_INTERNAL int scm_i_is_finalizer_thread (struct scm_thread *thread); + SCM_API int scm_set_automatic_finalization_enabled (int enabled_p); SCM_API int scm_run_finalizers (void); diff --git a/libguile/threads.c b/libguile/threads.c index 77e99da74..6b4510d53 100644 --- a/libguile/threads.c +++ b/libguile/threads.c @@ -1,4 +1,4 @@ -/* Copyright 1995-1998,2000-2014,2018-2019,2023-2024 +/* Copyright 1995-1998,2000-2014,2018-2019,2023-2025 Free Software Foundation, Inc. This file is part of Guile. @@ -47,6 +47,7 @@ #include "dynwind.h" #include "eval.h" #include "extensions.h" +#include "finalizers.h" #include "fluids.h" #include "gc-inline.h" #include "gc.h" @@ -1691,7 +1692,9 @@ SCM_DEFINE (scm_all_threads, "all-threads", 0, 0, 0, for (t = all_threads; t && n > 0; t = t->next_thread) { - if (!t->exited && !scm_i_is_signal_delivery_thread (t)) + if (!t->exited + && !scm_i_is_signal_delivery_thread (t) + && !scm_i_is_finalizer_thread (t)) { SCM_SETCAR (*l, t->handle); l = SCM_CDRLOC (*l);