8000 gh-128002: fix many thread safety issues in asyncio by kumaraditya303 · Pull Request #128147 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-128002: fix many thread safety issues in asyncio #128147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f3642ae
fix thread safety
kumaraditya303 Dec 21, 2024
1f63b9e
keep working
kumaraditya303 Dec 21, 2024
26e9932
keep working
kumaraditya303 Dec 21, 2024
4381ae2
fix refcounting
kumaraditya303 Dec 21, 2024
b972121
fix refcounting
kumaraditya303 Dec 21, 2024
eeb0273
add asserts
kumaraditya303 Dec 21, 2024
fd1b9cd
more asserts
kumaraditya303 Dec 21, 2024
b628463
more asserts
kumaraditya303 Dec 23, 2024
501b6bb
Merge branch 'main' of https://github.com/python/cpython into asyncio…
kumaraditya303 Dec 23, 2024
86448af
fix test
kumaraditya303 Dec 23, 2024
303bd9a
Merge branch 'main' of https://github.com/python/cpython into asyncio…
kumaraditya303 Dec 25, 2024
0e4a775
fix crash by using mutex instead of critical_section
kumaraditya303 Dec 25, 2024
1cb3a6f
fix all_tasks and use critical section as before
kumaraditya303 Dec 31, 2024
195c87d
add supressions
kumaraditya303 Dec 31, 2024
49f3393
Merge branch 'main' of https://github.com/python/cpython into asyncio…
kumaraditya303 Dec 31, 2024 8000
847da18
remove suppressions for sockets, it is fixed now
kumaraditya303 Jan 1, 2025
41a86a6
merge fixes for socket
kumaraditya303 Jan 1, 2025
2ff2af4
add link to issue in suppressions
kumaraditya303 Jan 2, 2025
5411a44
use list as temp storage for tasks before filtering
kumaraditya303 Jan 2, 2025
1afac5f
fix FutureIter_am_send_lock_held
kumaraditya303 Jan 2, 2025
606ef5c
make it->future immutable
kumaraditya303 Jan 2, 2025
f2ea4c6
Merge branch 'main' of https://github.com/python/cpython into asyncio…
kumaraditya303 Jan 3, 2025
8bd0da7
remove unnecessary incref/decref of task
kumaraditya303 Jan 3, 2025
5030cc6
remove suppressions
kumaraditya303 Jan 4, 2025
2676957
fix comment
kumaraditya303 Jan 4, 2025
6e60222
Update Tools/tsan/suppressions_free_threading.txt
kumaraditya303 Jan 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
use list as temp storage for tasks before filtering
  • Loading branch information
kumaraditya303 committed Jan 2, 2025
commit 5411a449dec631a9ae199ec7f6065182523b90a4
37 changes: 16 additions & 21 deletions Modules/_asynciomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3760,23 +3760,28 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop)
} else {
Py_INCREF(loop);
}
// First add eager tasks to the set so that we don't miss
// First add eager tasks to the list so that we don't miss
// any tasks which graduates from eager to non-eager
// We first add all the tasks to `tasks` set and then filter
// out the tasks which are done and return it.
PyObject *tasks = PySet_New(state->eager_tasks);
// We first add all the tasks to `tasks` list and then filter
// out the tasks which are done and return it as a set.
PyObject *tasks = PyList_New(0);
if (tasks == NULL) {
Py_DECREF(loop);
return NULL;
}
if (PyList_Extend(tasks, state->eager_tasks) < 0) {
Py_DECREF(tasks);
Py_DECREF(loop);
return NULL;
}
int err = 0;
ASYNCIO_STATE_LOCK(state);
struct llist_node *node;

llist_for_each_safe(node, &state->asyncio_tasks_head) {
TaskObj *task = llist_data(node, TaskObj, task_node);
Py_INCREF(task);
if (PySet_Add(tasks, (PyObject *)task) < 0) {
if (PyList_Append(tasks, (PyObject *)task) < 0) {
Py_DECREF(task);
Py_DECREF(tasks);
Py_DECREF(loop);
Expand All @@ -3797,7 +3802,7 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop)
}
PyObject *item;
while ((item = PyIter_Next(scheduled_iter)) != NULL) {
if (PySet_Add(tasks, item) < 0) {
if (PyList_Append(tasks, item) < 0) {
Py_DECREF(tasks);
Py_DECREF(loop);
Py_DECREF(item);
Expand All @@ -3807,34 +3812,24 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop)
Py_DECREF(item);
}
Py_DECREF(scheduled_iter);
// All the tasks are now in the set, now filter the tasks which are done
// All the tasks are now in the list, now filter the tasks which are done
PyObject *res = PySet_New(NULL);
if (res == NULL) {
Py_DECREF(tasks);
Py_DECREF(loop);
return NULL;
}
PyObject *iter = PyObject_GetIter(tasks);

if (iter == NULL) {
Py_DECREF(tasks);
Py_DECREF(res);
Py_DECREF(loop);
return NULL;
}

while((item = PyIter_Next(iter)) != NULL) {
if (add_one_task(state, res, item, loop) < 0) {
for (Py_ssize_t i = 0; i < PyList_GET_SIZE(tasks); i++) {
PyObject *task = PyList_GET_ITEM(tasks, i);
if (add_one_task(state, res, task, loop) < 0) {
Py_DECREF(res);
Py_DECREF(iter);
Py_DECREF(tasks);
Py_DECREF(loop);
Py_DECREF(item);
return NULL;
}
Py_DECREF(item);
}
Py_DECREF(iter);

Py_DECREF(tasks);
Py_DECREF(loop);
return res;
Expand Down
2 changes: 1 addition & 1 deletion Tools/tsan/suppressions_free_threading.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ race_top:write_thread_id
race_top:PyThreadState_Clear
# Only seen on macOS, sample: https://gist.github.com/aisk/dda53f5d494a4556c35dde1fce03259c
race_top:set_default_allocator_unlocked
# See https://github.com/python/cpython/pull/128147
# See https://github.com/python/cpython/issues/128421
race_top:_PyFrame_GetBytecode
race_top:BaseException_set_tb

Expand Down
0