Cannot resume a fiber that was earlier transferred from, then transferred back to, and then yielded
Consider the following code snippet:
require 'fiber' fiber2 = nil fiber1 = Fiber.new do puts "In Fiber 1" # 3 fiber2.transfer # 4 end fiber2 = Fiber.new do puts "In Fiber 2" # 1 fiber1.transfer # 2 puts "In Fiber 2 again" # 5 Fiber.yield # 6 puts "Fiber 2 resumed" # 10 end fiber3 = Fiber.new do puts "In Fiber 3" # 8 end fiber2.resume # 0 fiber3.resume # 7 fiber2.resume # 9
I have numbered the lines of code with the expected serial order of execution on the right. Once
fiber3.resume returns and I call
fiber2.resume, I expect the execution to continue inside
fiber2 at the line marked # 10. Instead, I get the following error:
fiber2.rb:24:in `resume': cannot resume transferred Fiber (FiberError) from fiber2.rb:24:in `<main>'
That's an error reported from the last line of the listing:
Updated by jeremyevans (Jeremy Evans) 10 months ago
- Status changed from Open to Closed
Applied in changeset git|fa8ac91e957a076f6df1adaecad7896817138009.
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.