Skip to content

Commit e76d333

Browse files
[3.14] GH-153809: Untrack TaskObj from GC before calling unregister_task (GH-154563) (#154666)
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 0c6dbac commit e76d333

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
@@ -2993,13 +2993,17 @@ TaskObj_dealloc(PyObject *self)
29932993
if (PyObject_CallFinalizerFromDealloc(self) < 0) {
29942994
return; // resurrected
29952995
}
2996+
// Untrack the object before unregistering the task, since the
2997+
// latter can cause a stop-the-world pause, after which another
2998+
// thread might call the GC and reach the object while it is
2999+
// semi-deallocated but still tracked
3000+
PyObject_GC_UnTrack(self);
3001+
29963002
// unregister the task after finalization so that
29973003
// if the task gets resurrected, it remains registered
29983004
unregister_task((TaskObj *)self);
29993005

30003006
PyTypeObject *tp = Py_TYPE(self);
3001-
PyObject_GC_UnTrack(self);
3002-
30033007
PyObject_ClearWeakRefs(self);
30043008

30053009
(void)TaskObj_clear(self);

0 commit comments

Comments
 (0)