gh-117657: Fix race involving GC and heap initialization (#119923)
The `_PyThreadState_Bind()` function is called before the first `PyEval_AcquireThread()` so it's not synchronized with the stop the world GC. We had a race where `gc_visit_heaps()` might visit a thread's heap while it's being initialized. Use a simple atomic int to avoid visiting heaps for threads that are not yet fully initialized (i.e., before `tstate_mimalloc_bind()` is called). The race was reproducible by running: `python Lib/test/test_importlib/partial/pool_in_threads.py`.
This commit is contained in:
@@ -252,6 +252,10 @@ gc_visit_heaps_lock_held(PyInterpreterState *interp, mi_block_visit_fun *visitor
|
||||
// visit each thread's heaps for GC objects
|
||||
for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) {
|
||||
struct _mimalloc_thread_state *m = &((_PyThreadStateImpl *)p)->mimalloc;
|
||||
if (!_Py_atomic_load_int(&m->initialized)) {
|
||||
// The thread may not have called tstate_mimalloc_bind() yet.
|
||||
continue;
|
||||
}
|
||||
|
||||
arg->offset = offset_base;
|
||||
if (!mi_heap_visit_blocks(&m->heaps[_Py_MIMALLOC_HEAP_GC], true,
|
||||
|
||||
Reference in New Issue
Block a user