class NIO::Selector

def select(timeout = nil)

Select which monitors are ready
def select(timeout = nil)
  @lock.synchronize do
    readers, writers = [@wakeup], []
    @selectables.each do |io, monitor|
      readers << io if monitor.interests == :r || monitor.interests == :rw
      writers << io if monitor.interests == :w || monitor.interests == :rw
      monitor.readiness = nil
    end
    ready_readers, ready_writers = Kernel.select readers, writers, [], timeout
    return unless ready_readers # timeout or wakeup
    
    selected_monitors = Set.new
    ready_readers.each do |io|
      if io == @wakeup
        # Clear all wakeup signals we've received by reading them
        # Wakeups should have level triggered behavior
        @wakeup.read(@wakeup.stat.size)
        return
      else
        monitor = @selectables[io]
        monitor.readiness = :r
        selected_monitors << monitor
      end
    end
    
    ready_writers.each do |io|
      monitor = @selectables[io]
      monitor.readiness = case monitor.readiness
      when :r
        :rw
      else
        :w
      end
      selected_monitors << monitor
    end
    
    if block_given?
      selected_monitors.each do |m|
        yield m
      end
      selected_monitors.size
    else
      selected_monitors
    end
  end
end