Skip to content

Commit 5062427

Browse files
GH-153809: Untrack TaskObj from GC before calling unregister_task (#154563)
1 parent 59e67c2 commit 5062427

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
@@ -2966,13 +2966,17 @@ TaskObj_dealloc(PyObject *self)
29662966
if (PyObject_CallFinalizerFromDealloc(self) < 0) {
29672967
return; // resurrected
29682968
}
2969+
// Untrack the object before unregistering the task, since the
2970+
// latter can cause a stop-the-world pause, after which another
2971+
// thread might call the GC and reach the object while it is
2972+
// semi-deallocated but still tracked
2973+
PyObject_GC_UnTrack(self);
2974+
29692975
// unregister the task after finalization so that
29702976
// if the task gets resurrected, it remains registered
29712977
unregister_task((TaskObj *)self);
29722978

29732979
PyTypeObject *tp = Py_TYPE(self);
2974-
PyObject_GC_UnTrack(self);
2975-
29762980
PyObject_ClearWeakRefs(self);
29772981

29782982
(void)TaskObj_clear(self);

0 commit comments

Comments
 (0)