lib/lightio/core/ioloop.rb in lightio-0.2.2 vs lib/lightio/core/ioloop.rb in lightio-0.3.0
- old
+ new
@@ -1,39 +1,24 @@
require 'lightio/core/backend/nio'
+require 'forwardable'
+
module LightIO::Core
# IOloop like a per-threaded EventMachine (cause fiber cannot resume cross threads)
#
# IOloop handle io waiting and schedule beams, user do not supposed to directly use this class
class IOloop
+ RAW_THREAD = ::Thread
+
def initialize
@fiber = Fiber.new {run}
@backend = Backend::NIO.new
end
- # should never invoke explicitly
- def run
- # start io loop and never return...
- @backend.run
- end
+ extend Forwardable
+ def_delegators :@backend, :run, :add_timer, :add_callback, :add_io_wait, :cancel_io_wait, :backend
- def add_timer(timer)
- @backend.add_timer(timer)
- end
-
- def add_callback(&blk)
- @backend.add_callback(&blk)
- end
-
- def add_io_wait(io, interests, &blk)
- @backend.add_io_wait(io, interests, &blk)
- end
-
- def cancel_io_wait(io)
- @backend.cancel_io_wait(io)
- end
-
# Wait a watcher, watcher can be a timer or socket.
# see LightIO::Watchers module for detail
def wait(watcher)
future = Future.new
# add watcher to loop
@@ -42,32 +27,35 @@
watcher.start(self)
# trigger a fiber switch
# wait until watcher is ok
# then do work
response_id, err = future.value
+ current_beam = LightIO::Core::Beam.current
if response_id != id
- raise InvalidTransferError, "expect #{id}, but get #{result}"
+ raise LightIO::InvalidTransferError, "expect #{id}, but get #{response_id}"
elsif err
# if future return a err
# simulate Thread#raise to Beam , that we can shutdown beam blocking by socket accepting
# transfer back to which beam occur this err
# not sure this is a right way to do it
- LightIO::Core::Beam.current.raise(err)
+ current_beam.raise(err) if current_beam.is_a?(LightIO::Core::Beam)
end
+ # check beam error after wait
+ current_beam.send(:check_and_raise_error) if current_beam.is_a?(LightIO::Core::Beam)
end
def transfer
@fiber.transfer
end
class << self
# return current ioloop or create new one
def current
key = :"lightio.ioloop"
- unless Thread.current.thread_variable?(key)
- Thread.current.thread_variable_set(key, IOloop.new)
+ unless RAW_THREAD.current.thread_variable?(key)
+ RAW_THREAD.current.thread_variable_set(key, IOloop.new)
end
- Thread.current.thread_variable_get(key)
+ RAW_THREAD.current.thread_variable_get(key)
end
end
end
end
\ No newline at end of file