def select(timeout = nil)
      selected_monitors = Set.new

      @lock.synchronize do
        readers = [@wakeup]
        writers = []

        @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

        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)
          else
            monitor = @selectables[io]
            monitor.readiness = :r
            selected_monitors << monitor
          end
        end

        ready_writers.each do |io|
          monitor = @selectables[io]
          monitor.readiness = monitor.readiness == :r ? :rw : :w
          selected_monitors << monitor
        end
      end

      if block_given?
        selected_monitors.each { |m| yield m }
        selected_monitors.size
      else
        selected_monitors.to_a
      end
    end
def select(timeout = nil)
      selected_monitors = Set.new

      @lock.synchronize do
        readers = [@wakeup]
        writers = []

        @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

        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)
          else
            monitor = @selectables[io]
            monitor.readiness = :r
            selected_monitors << monitor
          end
        end

        ready_writers.each do |io|
          monitor = @selectables[io]
          monitor.readiness = monitor.readiness == :r ? :rw : :w
          selected_monitors << monitor
        end
      end

      if block_given?
        selected_monitors.each { |m| yield m }
        selected_monitors.size
      else
        selected_monitors.to_a
      end
    end
Select which monitors are ready