https://github.com/python/cpython/commit/182bf2e72ff53de942c04420e383118c11c70c69
commit: 182bf2e72ff53de942c04420e383118c11c70c69
branch: main
author: Donghee Na <[email protected]>
committer: corona10 <[email protected]>
date: 2026-10-20T09:40:52-07:00
summary:
gh-159462: Relax the thread check in _PyMem_mi_page_reclaimed() (gh-159807)
files:
M Lib/test/test_free_threading/test_interpreters.py
M Objects/obmalloc.c
diff --git a/Lib/test/test_free_threading/test_interpreters.py
b/Lib/test/test_free_threading/test_interpreters.py
index a9a432fae16b1e1..09f7dbf99c3108a 100644
--- a/Lib/test/test_free_threading/test_interpreters.py
+++ b/Lib/test/test_free_threading/test_interpreters.py
@@ -1,6 +1,7 @@
import textwrap
import unittest
+from test import support
from test.support import import_helper, script_helper
@@ -24,6 +25,19 @@ def test_destroy_subinterpreter_does_not_abort(self):
""")
script_helper.assert_python_ok('-c', script)
+ @support.requires_resource('cpu')
+ def test_destroy_subinterpreter_with_abandoned_pages_does_not_abort(self):
+ # gh-159462: Py_EndInterpreter() clears a non-current thread state.
+ script = textwrap.dedent("""
+ import _testinternalcapi
+
+ interpid = _testinternalcapi.create_interpreter()
+ _testinternalcapi.exec_interpreter(
+ interpid, "objs = [[i] for i in range(400_000)]; del objs")
+ _testinternalcapi.destroy_interpreter(interpid, basic=True)
+ """)
+ script_helper.assert_python_ok('-c', script)
+
if __name__ == "__main__":
unittest.main()
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index 096b8b08aa73eba..502c3eea6806cfa 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -212,7 +212,10 @@ _PyMem_mi_page_reclaimed(mi_page_t *page)
if (mi_page_all_free(page)) {
assert(page->qsbr_node.next == NULL);
_PyThreadStateImpl *tstate = tstate_from_heap(mi_page_heap(page));
- assert(tstate == (_PyThreadStateImpl *)_PyThreadState_GET());
+ // gh-159462: the owning tstate may differ from the current
+ // one, but the heap is always owned by the current OS thread,
+ // so the page list is not shared with other OS threads.
+ assert(mi_page_heap(page)->thread_id == _Py_ThreadId());
page->retire_expire = 0;
llist_insert_tail(&tstate->mimalloc.page_list, &page->qsbr_node);
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]