class Puma::Reactor
def select_loop
def select_loop close_selector = true begin until @input.closed? && @input.empty? # Wakeup any registered object that receives incoming data. # Block until the earliest timeout or Selector#wakeup is called. timeout = (earliest = @timeouts.first) && earliest.timeout @selector.select(timeout) {|mon| wakeup!(mon.value)} # Wakeup all objects that timed out. timed_out = @timeouts.take_while {|t| t.timeout == 0} timed_out.each { |c| wakeup! c } unless @input.empty? until @input.empty? client = @input.pop register(client) if client.io_ok? end @timeouts.sort_by!(&:timeout_at) end end rescue StandardError => e STDERR.puts "Error in reactor loop escaped: #{e.message} (#{e.class})" STDERR.puts e.backtrace # NoMethodError may be rarely raised when calling @selector.select, which # is odd. Regardless, it may continue for thousands of calls if retried. # Also, when it raises, @selector.close also raises an error. if NoMethodError === e close_selector = false else retry end end # Wakeup all remaining objects on shutdown. @timeouts.each(&@block) @selector.close if close_selector end