GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-159449: Fix a free-threaded asyncio race that corrupts the task lists by jblespiau · Pull Request #159483 · python/cpython

Conversation

@jblespiau

@jblespiau jblespiau commented Oct 15, 2026 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

When a thread exits with pending asyncio Tasks, PyThreadState_Clear() moves them onto the shared interp->asyncio_tasks_head list, but each Task still records the _Py_ThreadId() of the thread that created it. unregister_task() skips the stop-the-world pause whenever that id matches the current thread. That also happens for a later thread that reuses the exited thread's pthread_t, and for destructors that run later in PyThreadState_Clear(). The resulting unlocked llist_remove() calls on the shared list race with each other and can leave an already-removed node (next == NULL) linked into it. asyncio.all_tasks(), which asyncio.run() calls on shutdown, then crashes with SIGSEGV in _asyncio_all_tasks().

Record the unique id (PyThreadState.id) of the creating thread state instead, and only take the lock-free path while that thread state is not being cleared.

Also drop the assertion in add_tasks_llist() that every linked Task is pending. A Task's state is set before unregister_task() unlinks it, and that removal can be waiting for the stop-the-world pause during which the list is walked. add_one_task() already filters out Tasks that are done.

3.14 fix is in #159451 that we can reopen if this one is accepted.

  • Issue: AsyncIO thread-safety issue in Python 3.14's free-threading #159449

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@jblespiau
pythongh-159449: Fix a free-threaded asyncio race that corrupts the t…
8e75acc
…ask lists

When a thread exits with pending asyncio Tasks, PyThreadState_Clear() moves them
onto the shared interp->asyncio_tasks_head list, but each Task still records the
_Py_ThreadId() of the thread that created it. unregister_task() skips the
stop-the-world pause whenever that id matches the current thread. That also
happens for a later thread that reuses the exited thread's pthread_t, and for
destructors that run later in PyThreadState_Clear(). The resulting unlocked
llist_remove() calls on the shared list race with each other and can leave an
already-removed node (next == NULL) linked into it. asyncio.all_tasks(), which
asyncio.run() calls on shutdown, then crashes with SIGSEGV in
_asyncio_all_tasks().

Record the unique id (PyThreadState.id) of the creating thread state instead,
and only take the lock-free path while that thread state is not being cleared.

Also drop the assertion in add_tasks_llist() that every linked Task is pending.
A Task's state is set before unregister_task() unlinks it, and that removal can
be waiting for the stop-the-world pause during which the list is walked.
add_one_task() already filters out Tasks that are done.
@jblespiau
jblespiau requested review from 1st1, asvetlov, kumaraditya303 and willingc as code owners October 15, 2026 18:45
@bedevere-app bedevere-app Bot mentioned this pull request Oct 15, 2026
AsyncIO thread-safety issue in Python 3.14's free-threading #159449
Closed
@bedevere-app bedevere-app Bot added the awaiting review label Oct 15, 2026
blurb-it Bot and others added 3 commits October 15, 2026 18:46
@blurb-it
📜🤖 Added by blurb_it.
e60bb19
@jblespiau
Remove extra blub-it file.
acea81d
@jblespiau
Merge branch 'main' into fix-asyncio-task-unregister-race
e79f79e
@python-cla-bot

python-cla-bot Bot commented Oct 15, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jblespiau

jblespiau commented Oct 28, 2026

Copy link
Copy Markdown
Contributor Author

Hi,

is there anything I could do to help unblock this PR? I don't know what is the expected review time for such bug-fixes. I don't know if they are reviewed in bulk every N-weeks or if we don't hear back after a few days it's a bad sign.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ngoldbaum

ngoldbaum commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

@kumaraditya303 I think this is related to #159073.

@jblespiau you're going to need to update this to account for changes made there.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ngoldbaum
ngoldbaum reviewed Oct 30, 2026
View reviewed changes
Comment thread Lib/test/test_asyncio/test_free_threading.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

jblespiau and others added 5 commits November 2, 2026 14:41
@jblespiau
Merge branch 'main' into fix-asyncio-task-unregister-race
78ffcac
@jblespiau
Remove comments and rebase to head.
58c83fc
@jblespiau
Merge branch 'main' of https://github.com/python/cpython into fix-asy…
3f23308
…ncio-task-unregister-race
@jblespiau
Restore main changes in _asynciomodule.c and remove comments
0def8d4
@jblespiau
Restore original comments.
5a64c43
@jblespiau

jblespiau commented Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

Updated and rebased on HEAD.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ngoldbaum
ngoldbaum reviewed Nov 2, 2026
View reviewed changes
Comment thread Modules/_asynciomodule.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

ngoldbaum
ngoldbaum reviewed Nov 2, 2026
View reviewed changes
Comment thread Lib/test/test_asyncio/test_free_threading.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@jblespiau

jblespiau commented Nov 4, 2026

Copy link
Copy Markdown
Contributor Author

I think it's done, and I rebased on head again. Github is showing me it's "processing updates".

if this version still need changes, maybe it would be easier if a Python maintainer takes over as they are more familar with the tooling, tests, code, etc. As there is a reproducer, it should already help quite a lot.

the test passes after the CL, and fails on the assert Assertion 'task->task_state == STATE_PENDING' failed (Aborted). from head, and with this removed, it fails with Fatal Python error: Segmentation fault.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jblespiau

jblespiau commented Nov 4, 2026

Copy link
Copy Markdown
Contributor Author

I don't know why, but what I see inthe PR isn't what I have in the branch in my fork:

main...jblespiau:cpython:fix-asyncio-task-unregister-race

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@kumaraditya303
Record the owning thread state in register_task() only and rework test
12ea214
@kumaraditya303
kumaraditya303 force-pushed the fix-asyncio-task-unregister-race branch from 5faa64f to 12ea214 Compare November 5, 2026 04:40
@kumaraditya303
fix comments
ab6f461
@kumaraditya303 kumaraditya303 added topic-asyncio needs backport to 3.14 bugs and security fixes needs backport to 3.15 bugs and security fixes labels Nov 5, 2026
kumaraditya303
kumaraditya303 reviewed Nov 5, 2026
View reviewed changes
Comment thread Modules/_asynciomodule.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

kumaraditya303 added 2 commits November 5, 2026 10:43
@kumaraditya303
Apply suggestion from @kumaraditya303
d472986
@kumaraditya303
Merge branch 'main' into fix-asyncio-task-unregister-race
d8ed8d2
kumaraditya303
kumaraditya303 approved these changes Nov 5, 2026
View reviewed changes
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting review labels Nov 5, 2026
@kumaraditya303
kumaraditya303 merged commit aaaf61c into python:main Nov 5, 2026
60 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@miss-islington-app

miss-islington-app Bot commented Nov 5, 2026

Copy link
Copy Markdown

Thanks @jblespiau for the PR, and @kumaraditya303 for merging it 🌮🎉.. I'm working now to backport this PR to: 3.14, 3.15.
🐍🍒⛏🤖

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting merge label Nov 5, 2026
@miss-islington-app

miss-islington-app Bot commented Nov 5, 2026

Copy link
Copy Markdown

Sorry, @jblespiau and @kumaraditya303, I could not cleanly backport this to 3.14 due to a conflict.

Please backport manually with cherry_picker, see the devguide for more information.

cherry_picker aaaf61ca62f0924d7b5134c2d237313d8be2215c 3.14
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@miss-islington-app miss-islington-app Bot assigned kumaraditya303 Nov 5, 2026
@bedevere-app

bedevere-app Bot commented Nov 5, 2026

Copy link
Copy Markdown

GH-161379 is a backport of this pull request to the 3.15 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 bugs and security fixes label Nov 5, 2026
kumaraditya303 added a commit to kumaraditya303/cpython that referenced this pull request Nov 5, 2026
@jblespiau @kumaraditya303
[3.14] pythongh-159449: Fix free-threaded asyncio race that corrupts …
abee7e4
…the task lists (pythonGH-159483)

(cherry picked from commit aaaf61c)

Co-authored-by: Jean-Baptiste Lespiau <[email protected]>
Co-authored-by: Kumar Aditya <[email protected]>
@bedevere-app

bedevere-app Bot commented Nov 5, 2026

Copy link
Copy Markdown

GH-161380 is a backport of this pull request to the 3.14 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.14 bugs and security fixes label Nov 5, 2026
kumaraditya303 added a commit that referenced this pull request Nov 5, 2026
@miss-islington @jblespiau @kumaraditya303
[3.15] gh-159449: Fix free-threaded asyncio race that corrupts the ta…
3619efa
…sk lists (GH-159483) (#161379)

gh-159449: Fix free-threaded asyncio race that corrupts the task lists (GH-159483)
(cherry picked from commit aaaf61c)

Co-authored-by: Jean-Baptiste Lespiau <[email protected]>
Co-authored-by: Kumar Aditya <[email protected]>
kumaraditya303 added a commit that referenced this pull request Nov 5, 2026
@kumaraditya303 @jblespiau
[3.14] gh-159449: Fix free-threaded asyncio race that corrupts the ta…
6e88927
…sk lists (GH-159483) (#161380)

(cherry picked from commit aaaf61c)

Co-authored-by: Jean-Baptiste Lespiau <[email protected]>
@bedevere-bot

bedevere-bot commented Nov 5, 2026

Copy link
Copy Markdown

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot AMD64 FreeBSD Refleaks 3.15 (tier-3) has failed when building commit 3619efa.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/2056/builds/487) and take a look at the build logs.
  4. Check if the failure is related to this commit (3619efa) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/2056/builds/487

Failed tests:

  • test.test_asyncio.test_ssl

Failed subtests:

  • test_remote_shutdown_receives_trailing_data - test.test_asyncio.test_ssl.TestSSL.test_remote_shutdown_receives_trailing_data

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/home/buildbot/buildarea/3.15.opsec-fbsd14.refleak/build/Lib/test/test_asyncio/test_ssl.py", line 1430, in test_remote_shutdown_receives_trailing_data
    self.loop.run_until_complete(client(srv.addr))
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "/home/buildbot/buildarea/3.15.opsec-fbsd14.refleak/build/Lib/asyncio/base_events.py", line 730, in run_until_complete
    return future.result()
           ~~~~~~~~~~~~~^^
  File "/home/buildbot/buildarea/3.15.opsec-fbsd14.refleak/build/Lib/test/test_asyncio/test_ssl.py", line 1414, in client
    await future
  File "/home/buildbot/buildarea/3.15.opsec-fbsd14.refleak/build/Lib/test/test_asyncio/test_ssl.py", line 1422, in wrapper
    meth(sock)
    ~~~~^^^^^^
  File "/home/buildbot/buildarea/3.15.opsec-fbsd14.refleak/build/Lib/test/test_asyncio/test_ssl.py", line 1368, in server
    self.assertEqual(data_len, CHUNK * SIZE)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 0 != 4194304
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@ngoldbaum ngoldbaum ngoldbaum left review comments
@kumaraditya303 kumaraditya303 kumaraditya303 approved these changes
@1st1 1st1 Awaiting requested review from 1st1 1st1 is a code owner
@asvetlov asvetlov Awaiting requested review from asvetlov asvetlov is a code owner
@willingc willingc Awaiting requested review from willingc willingc is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@kumaraditya303 kumaraditya303

Labels

topic-asyncio

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

4 participants

@jblespiau @ngoldbaum @bedevere-bot @kumaraditya303
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.