Method: Fiber#transfer
- Defined in:
- lib/cfiber.rb
#transfer(*args) ⇒ Object
Useful to implement coroutines.
FIXME: the tricky part is init. In the example above, f.transfer(100) triggers f.resume(100), which in turns reach g.transfer(101). This triggers g.yield(f.resume(101)) but this is wrong. One must atomically pause (yield) g and resume f.
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/cfiber.rb', line 135 def transfer(*args) if Fiber.current.nil? log.debug "" log.debug "cas 1" Thread.current[:__cfiber_transfer] = nil self.resume(*args) elsif Thread.current[:__cfiber_transfer].nil? log.debug "" log.debug "cas 2" log.debug "resuming #{self}" Thread.current[:__cfiber_transfer] = Fiber.current self.resume(*args) elsif Thread.current[:__cfiber_transfer].is_a?(Fiber) log.debug "" log.debug "cas 3" log.debug "pausing #{Fiber.current}" Thread.current[:__cfiber_transfer] = nil Fiber.yield(*args) #Fiber.yield(self.resume(*args)) # TODO: handle multiple coroutines else log.debug "" log.debug "cas 4" raise FiberError, "transfer mismatch" end end |