Sha256: 3973211fe7d0295f048bf79d244f6e8d930dee22ed59e57d7ab56cf8cb9bdf0a
Contents?: true
Size: 1.83 KB
Versions: 4
Compression:
Stored size: 1.83 KB
Contents
require_relative '../lib/iou' require 'socket' require 'fiber' class ::Fiber attr_accessor :__op_id end class Scheduler class Cancel < Exception end attr_reader :ring def initialize @ring = IOU::Ring.new @runqueue = [] end def switchpoint while true f, v = @runqueue.shift if f return f.transfer(v) end @ring.process_completions end end def fiber_wait(op_id) Fiber.current.__op_id = op_id v = switchpoint Fiber.current.__op_id = nil raise v if v.is_a?(Exception) v end def read(**args) f = Fiber.current id = ring.prep_read(**args) do |c| if c[:result] < 0 @runqueue << [f, RuntimeError.new('error')] else @runqueue << [f, c[:buffer]] end end fiber_wait(id) end def write(**args) f = Fiber.current id = ring.prep_write(**args) do |c| if c[:result] < 0 @runqueue << [f, RuntimeError.new('error')] else @runqueue << [f, c[:result]] end end fiber_wait(id) end def sleep(interval) f = Fiber.current id = ring.prep_timeout(interval: interval) do |c| if c[:result] == Errno::ECANCELED::Errno @runqueue << [f, c[:result]] else @runqueue << [f, c[:result]] end end fiber_wait(id) end def cancel_fiber_op(f) op_id = f.__op_id if op_id ring.prep_cancel(op_id) end end def move_on_after(interval) f = Fiber.current cancel_id = ring.prep_timeout(interval: interval) do |c| if c[:result] != Errno::ECANCELED::Errno cancel_fiber_op(f) end end v = yield ring.prep_cancel(cancel_id) v end end s = Scheduler.new puts "Going to sleep..." s.sleep 3 puts "Woke up" s.move_on_after(1) do puts "Going to sleep (move on after 1 second)" s.sleep 3 end
Version data entries
4 entries across 4 versions & 2 rubygems
Version | Path |
---|---|
uringmachine-0.3 | examples/fibers.rb |
uringmachine-0.2 | examples/fibers.rb |
uringmachine-0.1 | examples/fibers.rb |
iou-0.2 | examples/fibers.rb |