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

relax Fiber#transfer's restriction #3636

Merged
merged 1 commit into from
Oct 12, 2020
Merged

Conversation

ko1
Copy link
Contributor

@ko1 ko1 commented Oct 7, 2020

Using Fiber#transfer with Fiber#resume for a same Fiber is
limited (once Fiber#transfer is called for a fiber, the fiber
can not resume more). This restriction is introduced to protect
the resume/yield chain, but we realized that it is too much to
protect the resume/yield chain. Instead of the current restriction,
we introduce some other protection.

(1) can not transfer to the resuming fiber.
(2) can not transfer to the yielding fiber.
(3) can not resume transferred fiber.

https://bugs.ruby-lang.org/issues/17221

@ko1 ko1 force-pushed the relax_fiber_transfer branch 2 times, most recently from 012e9f9 to f307a72 Compare October 8, 2020 00:42
@ko1 ko1 force-pushed the relax_fiber_transfer branch 2 times, most recently from 35defef to f008d5a Compare October 9, 2020 19:38
@@ -409,5 +480,5 @@ def test_machine_stack_gc
sleep 5 # pause until thread cache wait time runs out. Native thread exits.
GC.start
RUBY
end
end if false
Copy link
Member

Choose a reason for hiding this comment

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

Intentional?

end
ruby_version_is '3.0' do
fiber2.resume.should == :fiber2
end
Copy link
Member

Choose a reason for hiding this comment

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

It's better to have ruby_version_is outside of it "description" do, so the description can explain the difference in behavior. I can do that after this PR is merged.

cont.c Outdated
rb_raise(rb_eFiberError, "attempt to transfer to a resuming fiber");
}
if (fiber->yielding) {
rb_raise(rb_eFiberError, "attempt to transfer to an yielding fiber");
Copy link
Member

Choose a reason for hiding this comment

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

to a yielding fiber (replied on Redmine)

@ko1 ko1 force-pushed the relax_fiber_transfer branch 2 times, most recently from cceb892 to 6b7bd36 Compare October 12, 2020 04:53
Using Fiber#transfer with Fiber#resume for a same Fiber is
limited (once Fiber#transfer is called for a fiber, the fiber
can not be resumed more). This restriction was introduced to
protect the resume/yield chain, but we realized that it is too much
to protect the chain. Instead of the current restriction, we
introduce some other protections.

(1) can not transfer to the resuming fiber.
(2) can not transfer to the yielding fiber.
(3) can not resume transferred fiber.
(4) can not yield from not-resumed fiber.

[Bug #17221]

Also at the end of a transferred fiber, it had continued on root fiber.
However, if the root fiber resumed a fiber (and that fiber can resumed
another fiber), this behavior also breaks the resume/yield chain.
So at the end of a transferred fiber, switch to the edge of resume
chain from root fiber.
For example, root fiber resumed f1 and f1 resumed f2, transferred to
f3 and f3 terminated, then continue from the fiber f2 (it was continued
from root fiber without this patch).
@ko1 ko1 merged commit bf3b2a4 into ruby:master Oct 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants