lib/httpx/selector.rb in httpx-0.4.1 vs lib/httpx/selector.rb in httpx-0.5.0

- old
+ new

@@ -46,84 +46,69 @@ end # :nocov: end def initialize - @readers = {} - @writers = {} + @selectables = {} @__r__, @__w__ = IO.pipe @closed = false end # deregisters +io+ from selectables. def deregister(io) - rmonitor = @readers.delete(io) - wmonitor = @writers.delete(io) - monitor = rmonitor || wmonitor + monitor = @selectables.delete(io) monitor.close(false) if monitor end # register +io+ for +interests+ events. def register(io, interests) - readable = READABLE.include?(interests) - writable = WRITABLE.include?(interests) - if readable - monitor = @readers[io] - if monitor - monitor.interests = interests - else - monitor = Monitor.new(io, interests, self) - end - @readers[io] = monitor - @writers.delete(io) unless writable + monitor = @selectables[io] + if monitor + monitor.interests = interests + else + monitor = Monitor.new(io, interests, self) + @selectables[io] = monitor end - if writable - monitor = @writers[io] - if monitor - monitor.interests = interests - else - # reuse object - monitor = readable ? @readers[io] : Monitor.new(io, interests, self) - end - @writers[io] = monitor - @readers.delete(io) unless readable - end monitor end # waits for read/write events for +interval+. Yields for monitors of # selected IO objects. # def select(interval) begin - r = @readers.keys - w = @writers.keys - r.unshift(@__r__) + r = [@__r__] + w = [] + @selectables.each do |io, monitor| + r << io if monitor.interests == :r || monitor.interests == :rw + w << io if monitor.interests == :w || monitor.interests == :rw + monitor.readiness = nil + end + readers, writers = IO.select(r, w, nil, interval) raise HTTPX::TimeoutError.new(interval, "timed out while waiting on select") if readers.nil? && writers.nil? rescue IOError, SystemCallError - @readers.reject! { |io, _| io.closed? } - @writers.reject! { |io, _| io.closed? } + @selectables.reject! { |io, _| io.closed? } retry end readers.each do |io| if io == @__r__ # clean up wakeups @__r__.read(@__r__.stat.size) else - monitor = io.closed? ? @readers.delete(io) : @readers[io] + monitor = io.closed? ? @selectables.delete(io) : @selectables[io] next unless monitor monitor.readiness = writers.delete(io) ? :rw : :r yield monitor end end if readers writers.each do |io| - monitor = io.closed? ? @writers.delete(io) : @writers[io] + monitor = io.closed? ? @selectables.delete(io) : @selectables[io] next unless monitor # don't double run this, the last iteration might have run this task already monitor.readiness = :w yield monitor