summaryrefslogtreecommitdiffstats
path: root/Python/gc_free_threading.c
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-06-03 22:21:32 (GMT)
committerGitHub <noreply@github.com>2024-06-03 22:21:32 (GMT)
commitae705319fcde864b504987dc8e579e3eef68e1e5 (patch)
tree022166446a352d99b784b44a86f163bec179e94d /Python/gc_free_threading.c
parentca37034baa2909722df58c02dfd13e1d667252ce (diff)
downloadcpython-ae705319fcde864b504987dc8e579e3eef68e1e5.zip
cpython-ae705319fcde864b504987dc8e579e3eef68e1e5.tar.gz
cpython-ae705319fcde864b504987dc8e579e3eef68e1e5.tar.bz2
[3.13] gh-117657: Fix race involving immortalizing objects (GH-119927) (#120005)
The free-threaded build currently immortalizes objects that use deferred reference counting (see gh-117783). This typically happens once the first non-main thread is created, but the behavior can be suppressed for tests, in subinterpreters, or during a compile() call. This fixes a race condition involving the tracking of whether the behavior is suppressed. (cherry picked from commit 47fb4327b5c405da6df066dcaa01b7c1aefab313)
Diffstat (limited to 'Python/gc_free_threading.c')
-rw-r--r--Python/gc_free_threading.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index e6bd012..d005b79 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -703,11 +703,9 @@ _PyGC_Init(PyInterpreterState *interp)
{
GCState *gcstate = &interp->gc;
- if (_Py_IsMainInterpreter(interp)) {
- // gh-117783: immortalize objects that would use deferred refcounting
- // once the first non-main thread is created.
- gcstate->immortalize.enable_on_thread_created = 1;
- }
+ // gh-117783: immortalize objects that would use deferred refcounting
+ // once the first non-main thread is created (but not in subinterpreters).
+ gcstate->immortalize = _Py_IsMainInterpreter(interp) ? 0 : -1;
gcstate->garbage = PyList_New(0);
if (gcstate->garbage == NULL) {
@@ -1808,8 +1806,10 @@ _PyGC_ImmortalizeDeferredObjects(PyInterpreterState *interp)
{
struct visitor_args args;
_PyEval_StopTheWorld(interp);
- gc_visit_heaps(interp, &immortalize_visitor, &args);
- interp->gc.immortalize.enabled = 1;
+ if (interp->gc.immortalize == 0) {
+ gc_visit_heaps(interp, &immortalize_visitor, &args);
+ interp->gc.immortalize = 1;
+ }
_PyEval_StartTheWorld(interp);
}