Skip to content
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

gh-126366: Make native generators thread safe #126371

Open
wants to merge 21 commits into
base: main
Choose a base branch
from

Conversation

ZeroIntensity
Copy link
Member

@ZeroIntensity ZeroIntensity commented Nov 3, 2024

@corona10
Copy link
Member

corona10 commented Nov 3, 2024

cc @colesbury

@corona10
Copy link
Member

corona10 commented Nov 3, 2024

I will try to take a look at today :)

Objects/listobject.c Outdated Show resolved Hide resolved
@ZeroIntensity ZeroIntensity changed the title gh-126366: Lock generic iterables in list.__init__ gh-126366: Make native generators thread safe Nov 4, 2024
@ZeroIntensity
Copy link
Member Author

Closing in favor of #120327

@Fidget-Spinner
Copy link
Member

Wait I closed my PR in favour of yours... 😆 @ZeroIntensity

@ZeroIntensity
Copy link
Member Author

Ah! I'll reopen this and list you as a co-author if yours has merge conflicts.

@ZeroIntensity ZeroIntensity reopened this Nov 6, 2024
@@ -1104,8 +1104,10 @@ dummy_func(
(Py_TYPE(receiver_o) == &PyGen_Type || Py_TYPE(receiver_o) == &PyCoro_Type) &&
((PyGenObject *)receiver_o)->gi_frame_state < FRAME_EXECUTING)
{
_PyInterpreterFrame *gen_frame;
Copy link
Member

Choose a reason for hiding this comment

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

I have a feeling you'll need to fix the specializations too. But right now they aren't enabled, so no way to test them until Matt re-enables them :(.

Copy link
Member Author

Choose a reason for hiding this comment

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

PTAL at GH-127426 and #127426 (comment) now. I think we're good for the specializations.

Lib/test/test_generators.py Outdated Show resolved Hide resolved
Lib/test/test_free_threading/test_generators.py Outdated Show resolved Hide resolved
Lib/test/test_free_threading/test_generators.py Outdated Show resolved Hide resolved
int exc, int closing)
{
PySendResult result;
Py_BEGIN_CRITICAL_SECTION(gen);
Copy link
Member

Choose a reason for hiding this comment

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

If we start to put locks, maybe other functions would deserve that lock as well:

  • _PyGen_yf()
  • gen_close()
  • _gen_throw()
  • _gen_getframe()

What about these getters?

  • gen_getrunning()
  • gen_getsuspended()

In frameobject.c, see frame_is_suspended() (should be safe).

In ceval.c, see clear_gen_frame().

PyGenObject *gen = (PyGenObject *)receiver_o;
_PyInterpreterFrame *gen_frame = &gen->gi_iframe;
Py_BEGIN_CRITICAL_SECTION(gen);
Copy link
Member

Choose a reason for hiding this comment

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

What about _SEND_GEN_FRAME, YIELD_VALUE, _FOR_ITER_GEN_FRAME and RETURN_GENERATOR instructions?

Copy link
Member Author

@ZeroIntensity ZeroIntensity Dec 20, 2024

Choose a reason for hiding this comment

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

I'm not sure we need to mess with things like YIELD_VALUE. A thread can't yield another thread's generator, can it?

Edit: Well, actually, I'll check. Sending to a generator that's yielding might break things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants