class Net::SSH::Connection::EventLoop
and we don’t pass session.
case you’re using multiple sessions in an event loop it doesnt makes sense
they should get current session as parameter, but in
one issue is with blocks passed to loop, etc.
EventLoop can be shared across multiple sessions
def ev_preprocess(&block)
Call preprocess on each session. If block given and that
def ev_preprocess(&block) return false if block_given? && !yield(self) @sessions.each(&:ev_preprocess) return false if block_given? && !yield(self) return true end
def ev_select_and_postprocess(wait)
def ev_select_and_postprocess(wait) owners = {} r = [] w = [] minwait = nil @sessions.each do |session| sr, sw, actwait = session.ev_do_calculate_rw_wait(wait) minwait = actwait if actwait && (minwait.nil? || actwait < minwait) r.push(*sr) w.push(*sw) sr.each { |ri| owners[ri] = session } sw.each { |wi| owners[wi] = session } end readers, writers, = IO.select(r, w, nil, minwait) fired_sessions = {} if readers readers.each do |reader| session = owners[reader] (fired_sessions[session] ||= { r: [], w: [] })[:r] << reader end end if writers writers.each do |writer| session = owners[writer] (fired_sessions[session] ||= { r: [], w: [] })[:w] << writer end end fired_sessions.each do |s, rw| s.ev_do_handle_events(rw[:r], rw[:w]) end @sessions.each { |s| s.ev_do_postprocess(fired_sessions.key?(s)) } true end
def initialize(logger = nil)
def initialize(logger = nil) self.logger = logger @sessions = [] end
def process(wait = nil, &block)
if a block is given a session will be removed from loop
process until timeout
def process(wait = nil, &block) return false unless ev_preprocess(&block) ev_select_and_postprocess(wait) end
def process_only(session, wait = nil)
def process_only(session, wait = nil) orig_sessions = @sessions begin @sessions = [session] return false unless ev_preprocess ev_select_and_postprocess(wait) ensure @sessions = orig_sessions end end
def register(session)
def register(session) @sessions << session end