Skip to content

Commit 8f99c7a

Browse files
[3.15] GH-153809: Untrack TaskObj from GC before calling unregister_task (GH-154563) (#154665)
GH-153809: Untrack TaskObj from GC before calling unregister_task (GH-154563) (cherry picked from commit 5062427) Co-authored-by: Sergey Miryanov <sergey.miryanov@gmail.com>
1 parent b4d0b26 commit 8f99c7a

2 files changed

Lines changed: 8 additions & 2 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix interpreter crash while deallocating objects of :class:`asyncio.Task` on
2+
free-threaded builds. Contributed by Sergey Miryanov.

Modules/_asynciomodule.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2974,13 +2974,17 @@ TaskObj_dealloc(PyObject *self)
29742974
if (PyObject_CallFinalizerFromDealloc(self) < 0) {
29752975
return; // resurrected
29762976
}
2977+
// Untrack the object before unregistering the task, since the
2978+
// latter can cause a stop-the-world pause, after which another
2979+
// thread might call the GC and reach the object while it is
2980+
// semi-deallocated but still tracked
2981+
PyObject_GC_UnTrack(self);
2982+
29772983
// unregister the task after finalization so that
29782984
// if the task gets resurrected, it remains registered
29792985
unregister_task((TaskObj *)self);
29802986

29812987
PyTypeObject *tp = Py_TYPE(self);
2982-
PyObject_GC_UnTrack(self);
2983-
29842988
PyObject_ClearWeakRefs(self);
29852989

29862990
(void)TaskObj_clear(self);

0 commit comments

Comments
 (0)