diff options
author | Sam Gross <colesbury@gmail.com> | 2024-06-03 16:58:41 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-03 20:58:41 +0000 |
commit | 47fb4327b5c405da6df066dcaa01b7c1aefab313 (patch) | |
tree | 8b5e04508b3cdced61e56eb200c4fc46a50ed11d /Python/gc_free_threading.c | |
parent | b8fde5db86334690da23343f5f4326adcd8160fb (diff) | |
download | cpython-47fb4327b5c405da6df066dcaa01b7c1aefab313.tar.gz cpython-47fb4327b5c405da6df066dcaa01b7c1aefab313.zip |
gh-117657: Fix race involving immortalizing objects (#119927)
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.
Diffstat (limited to 'Python/gc_free_threading.c')
-rw-r--r-- | Python/gc_free_threading.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index e6bd012c40e..d005b79ff40 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); } |