Project

General

Profile

Bug #6117

Transfers allowed into Fibers that have resumed into other fibers

Added by loganb (Logan Bowers) over 7 years ago. Updated 26 days ago.

Status:
Feedback
Priority:
Normal
Target version:
-
ruby -v:
ruby 2.0.0dev (2012-03-06) [x86_64-darwin11.3.0]
Backport:
[ruby-core:43088]

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.

History

Updated by mrkn (Kenta Murata) over 7 years ago

  • Assignee set to ko1 (Koichi Sasada)
#2

Updated by shyouhei (Shyouhei Urabe) over 7 years ago

  • Status changed from Open to Assigned

Updated by ko1 (Koichi Sasada) about 7 years ago

  • Target version set to 2.0.0

Please give me a time.

Updated by ko1 (Koichi Sasada) almost 7 years ago

Exception seems good.
transfer' andresume' should not be mix.

Any volunteer?
or it will be tagged `next minor'.

Updated by ko1 (Koichi Sasada) almost 7 years ago

Any volunteers?

Updated by ko1 (Koichi Sasada) almost 7 years ago

  • Target version changed from 2.0.0 to 2.6

no volunteer.

#7

Updated by ko1 (Koichi Sasada) about 4 years ago

  • Description updated (diff)
  • Status changed from Assigned to Feedback

Updated by ko1 (Koichi Sasada) almost 3 years ago

Can we change this spec yet?

Updated by jeremyevans0 (Jeremy Evans) 26 days 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.

Also available in: Atom PDF