ruby-changes:58351
From: Jeremy <ko1@a...>
Date: Tue, 22 Oct 2019 08:55:16 +0900 (JST)
Subject: [ruby-changes:58351] fa8ac91e95 (master): Fix Fiber#transfer
https://git.ruby-lang.org/ruby.git/commit/?id=fa8ac91e95 From fa8ac91e957a076f6df1adaecad7896817138009 Mon Sep 17 00:00:00 2001 From: Jeremy Evans <code@j...> Date: Mon, 21 Oct 2019 16:54:58 -0700 Subject: Fix Fiber#transfer Fiber#transfer previously made it impossible to resume the fiber if it was transferred to (no resuming the target of Fiber#transfer). However, the documentation specifies that you cannot resume a fiber that has transferred to another fiber (no resuming the source of Fiber#transfer), unless control is transferred back. Fix the code by setting the transferred flag on the current/source fiber, and unsetting the transferred flag on the target fiber. Fixes [Bug #9664] Fixes [Bug #12555] diff --git a/cont.c b/cont.c index 61f42b3..8e1dc6d 100644 --- a/cont.c +++ b/cont.c @@ -2226,7 +2226,8 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/cont.c#L2226 rb_fiber_m_transfer(int argc, VALUE *argv, VALUE fiber_value) { rb_fiber_t *fiber = fiber_ptr(fiber_value); - fiber->transferred = 1; + fiber_current()->transferred = 1; + fiber->transferred = 0; return fiber_switch(fiber, argc, argv, 0, PASS_KW_SPLAT); } diff --git a/spec/ruby/library/fiber/transfer_spec.rb b/spec/ruby/library/fiber/transfer_spec.rb index d130536..fa094a0 100644 --- a/spec/ruby/library/fiber/transfer_spec.rb +++ b/spec/ruby/library/fiber/transfer_spec.rb @@ -42,9 +42,18 @@ describe "Fiber#transfer" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/library/fiber/transfer_spec.rb#L42 fiber2.transfer.should == [:fiber2_start, :fiber1, :fiber2_end] end - it "raises a FiberError when transferring to a Fiber which resumes itself" do - fiber = Fiber.new { fiber.resume } - -> { fiber.transfer }.should raise_error(FiberError) + ruby_version_is ''...'2.7' do + it "raises a FiberError when transferring to a Fiber which resumes itself" do + fiber = Fiber.new { fiber.resume } + -> { fiber.transfer }.should raise_error(FiberError) + end + end + + ruby_version_is '2.7' do + it "allows transferring to a Fiber which resumes itself" do + fiber = Fiber.new { fiber.resume 1 } + fiber.transfer.should == 1 + end end it "works if Fibers in different Threads each transfer to a Fiber in the same Thread" do diff --git a/test/ruby/test_fiber.rb b/test/ruby/test_fiber.rb index 2d7cbc8..aa47aaf 100644 --- a/test/ruby/test_fiber.rb +++ b/test/ruby/test_fiber.rb @@ -222,8 +222,8 @@ class TestFiber < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_fiber.rb#L222 end def test_resume_self - f = Fiber.new {f.resume} - assert_raise(FiberError, '[ruby-core:23651]') {f.transfer} + f = Fiber.new {f.resume 1} + assert_equal(1, f.transfer) end def test_fiber_transfer_segv @@ -289,14 +289,12 @@ class TestFiber < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_fiber.rb#L289 assert_raise(FiberError){ g=nil f=Fiber.new{ - g.resume - g.resume + g.transfer } g=Fiber.new{ f.resume - f.resume } - f.transfer + f.resume } end -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/