[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]