Bug #6117
closedTransfers allowed into Fibers that have resumed into other fibers
Description
Consider the following code:
require 'fiber'
def foo
order = []
main_fiber = Fiber.current
a = Fiber.new do
order << 2
x = Fiber.new do
order << 4
main_fiber.transfer
order << 6
end
order << 3
x.resume
order << 7
end
order << 1
a.transfer
order << 5
a.transfer
order << 8
end
It produces output:
[1, 2, 3, 4, 5, 7, 8]
Note: the missing 6. I'd expect either the array to be 1-8 OR for an exception to be raised after 5 when the main fiber attempts to transfer into a again.
Either it shouldn't be possible to transfer into a Fiber that is blocked resuming another Fiber, OR it should automatically resume the sub-Fiber.
Updated by mrkn (Kenta Murata) about 12 years ago
- Assignee set to ko1 (Koichi Sasada)
Updated by shyouhei (Shyouhei Urabe) about 12 years ago
- Status changed from Open to Assigned
Updated by ko1 (Koichi Sasada) over 11 years ago
Exception seems good.
transfer' and
resume' should not be mix.
Any volunteer?
or it will be tagged `next minor'.
Updated by ko1 (Koichi Sasada) about 11 years ago
Any volunteers?
Updated by ko1 (Koichi Sasada) about 11 years ago
- Target version changed from 2.0.0 to 2.6
no volunteer.
Updated by ko1 (Koichi Sasada) over 8 years ago
- Description updated (diff)
- Status changed from Assigned to Feedback
Updated by ko1 (Koichi Sasada) about 7 years ago
Can we change this spec yet?
Updated by jeremyevans0 (Jeremy Evans) over 4 years ago
- Assignee changed from ko1 (Koichi Sasada) to ioquatix (Samuel Williams)
I do not think this code is actually a problem. The restriction on transferred fibers is:
You cannot resume a fiber that transferred control to another one.
This will cause a double resume error. You need to transfer control
back to this fiber before it can yield and resume.
That is not happening in this case. main_fiber
transfers to a
, which resumes x
, which transfers back to main_fiber
, which transfers again to a
. At no point is a fiber that has transferred control to another fiber resumed before control is transferred back to the fiber.
In the example given x
is not transferred back to after it transfers to main_fiber
, which is why 6
does not appear in the output. You can fix this by having a
transfer to x
after it is transferred back to (the second time) from main_fiber
:
require 'fiber'
def foo
order = []
main_fiber = Fiber.current
a = Fiber.new do
order << 2
x = Fiber.new do
order << 4
main_fiber.transfer
order << 6
end
order << 3
x.resume
x.transfer
order << 7
end
order << 1
a.transfer
order << 5
a.transfer
order << 8
end
Assinging to @ioquatix (Samuel Williams) to determine if this is actually a bug.
Updated by jeremyevans0 (Jeremy Evans) over 3 years ago
- Status changed from Feedback to Closed