module Polyphony::FiberControlClassMethods
Class methods for controlling fibers (namely await and select)
Public Instance Methods
await(*fibers)
click to toggle source
# File lib/polyphony/extensions/fiber.rb, line 117 def await(*fibers) return [] if fibers.empty? current_fiber = self.current mailbox = current_fiber.monitor_mailbox results = {} fibers.each do |f| results[f] = nil if f.dead? # fiber already terminated, so queue message mailbox << [f, f.result] else f.monitor(current_fiber) end end exception = nil while !fibers.empty? (fiber, result) = mailbox.shift next unless fibers.include?(fiber) fibers.delete(fiber) current_fiber.remove_child(fiber) if fiber.parent == current_fiber if result.is_a?(Exception) exception ||= result fibers.each { |f| f.terminate } else results[fiber] = result end end raise exception if exception results.values end
Also aliased as: join
schedule_priority_oob_fiber(&block)
click to toggle source
Creates and schedules with priority an out-of-band fiber that runs the supplied block. If any uncaught exception is raised while the fiber is running, it will bubble up to the main thread's main fiber, which will also be scheduled with priority. This method is mainly used trapping signals (see also the patched `Kernel#trap`)
# File lib/polyphony/extensions/fiber.rb, line 181 def schedule_priority_oob_fiber(&block) f = Fiber.new do Fiber.current.setup_raw block.call rescue Exception => e Thread.current.schedule_and_wakeup(Thread.main.main_fiber, e) end Thread.current.schedule_and_wakeup(f, nil) end
select(*fibers)
click to toggle source
# File lib/polyphony/extensions/fiber.rb, line 150 def select(*fibers) return nil if fibers.empty? current_fiber = self.current mailbox = current_fiber.monitor_mailbox fibers.each do |f| if f.dead? result = f.result result.is_a?(Exception) ? (raise result) : (return [f, result]) end end fibers.each { |f| f.monitor(current_fiber) } while true (fiber, result) = mailbox.shift next unless fibers.include?(fiber) fibers.each { |f| f.unmonitor(current_fiber) } if result.is_a?(Exception) raise result else return [fiber, result] end end end