https://github.com/python/cpython/commit/7dc41ad6a7826ffc675f088972de96624917696e
commit: 7dc41ad6a7826ffc675f088972de96624917696e
branch: main
author: Kumar Aditya <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2025-01-09T21:26:00+05:30
summary:
gh-128002: fix `asyncio.all_tasks` against concurrent deallocations of tasks
(#128541)
files:
M Include/internal/pycore_object.h
M Modules/_asynciomodule.c
diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h
index d7d68f938a9f0a..e26cb7673f939c 100644
--- a/Include/internal/pycore_object.h
+++ b/Include/internal/pycore_object.h
@@ -120,7 +120,7 @@ PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc(
PyAPI_DATA(Py_ssize_t) _Py_RefTotal;
extern void _Py_AddRefTotal(PyThreadState *, Py_ssize_t);
-extern void _Py_IncRefTotal(PyThreadState *);
+extern PyAPI_FUNC(void) _Py_IncRefTotal(PyThreadState *);
extern void _Py_DecRefTotal(PyThreadState *);
# define _Py_DEC_REFTOTAL(interp) \
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index b8b184af04a7cb..48f0ef95934fa4 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -3772,11 +3772,20 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject
*loop)
llist_for_each_safe(node, &state->asyncio_tasks_head) {
TaskObj *task = llist_data(node, TaskObj, task_node);
- if (PyList_Append(tasks, (PyObject *)task) < 0) {
- Py_DECREF(tasks);
- Py_DECREF(loop);
- err = 1;
- break;
+ // The linked list holds borrowed references to task
+ // as such it is possible that the task is concurrently
+ // deallocated while added to this list.
+ // To protect against concurrent deallocations,
+ // we first try to incref the task which would fail
+ // if it is concurrently getting deallocated in another thread,
+ // otherwise it gets added to the list.
+ if (_Py_TryIncref((PyObject *)task)) {
+ if (_PyList_AppendTakeRef((PyListObject *)tasks, (PyObject *)task)
< 0) {
+ Py_DECREF(tasks);
+ Py_DECREF(loop);
+ err = 1;
+ break;
+ }
}
}
ASYNCIO_STATE_UNLOCK(state);
_______________________________________________
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]