Skip to content

Conversation

@colesbury
Copy link
Contributor

@colesbury colesbury commented Dec 11, 2025

This makes generator frame state transitions atomic in the free threading build, which avoids segfaults when trying to execute a generator from multiple threads concurrently.

There are still a few operations that aren't thread-safe and may crash if performed concurrently on the same generator/coroutine:

  • Accessing gi_yieldfrom/cr_await/ag_await
  • Accessing gi_frame/cr_frame/ag_frame
  • Async generator operations

This makes generator frame state transitions atomic in the free
threading build, which avoids segfaults when trying to execute
a generator from multiple threads concurrently.

There are still a few operations that aren't thread-safe and may crash
if performed concurrently on the same generator/coroutine:

 * Accessing gi_yieldfrom/cr_await/ag_await
 * Accessing gi_frame/cr_frame/ag_frame
 * Async generator operations
@colesbury colesbury marked this pull request as ready for review December 12, 2025 16:44
@colesbury colesbury requested a review from mpage December 12, 2025 16:44
@colesbury colesbury added the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Dec 12, 2025
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @colesbury for commit ac3974d 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F142599%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-refleak-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Dec 12, 2025
Comment on lines +1425 to +1428
FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg);
#ifdef Py_GIL_DISABLED
((_PyThreadStateImpl *)tstate)->gen_last_frame_state = FRAME_SUSPENDED + oparg;
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to factor this out into a helper function? It's duplicated in ceval.c. Also, having helper to update both would reduce the chance that we update one without the other.

Comment on lines +54 to +55
if (gen->gi_frame_state < FRAME_EXECUTING) {
gen->gi_frame_state = FRAME_EXECUTING;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these loads need to use atomics (in the FT build)?

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants