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) over 13 years ago
- Assignee set to ko1 (Koichi Sasada)
Updated by shyouhei (Shyouhei Urabe) over 13 years ago
- Status changed from Open to Assigned
Updated by ko1 (Koichi Sasada) about 13 years ago
- Target version set to 2.0.0
Please give me a time.
Updated by ko1 (Koichi Sasada) almost 13 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) almost 13 years ago
Any volunteers?
Updated by ko1 (Koichi Sasada) almost 13 years ago
- Target version changed from 2.0.0 to 2.6
no volunteer.
Updated by ko1 (Koichi Sasada) about 10 years ago
- Description updated (diff)
- Status changed from Assigned to Feedback
Updated by ko1 (Koichi Sasada) almost 9 years ago
Can we change this spec yet?
Updated by jeremyevans0 (Jeremy Evans) about 6 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 5 years ago
- Status changed from Feedback to Closed