about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-12-27 08:08:50 +0000
committerEric Wong <normalperson@yhbt.net>2013-12-27 08:08:50 +0000
commit156bce1e6349fd6ae921bad59ad0b93081946b0c (patch)
tree93bb0c6e9a03599b2fc4248e761f19f4908643af
parentdf634904b60f0aa17a99afd225c58a7605c9ee37 (diff)
downloaddtas-156bce1e6349fd6ae921bad59ad0b93081946b0c.tar.gz
This keeps us from doing an extra IO.select when we know the sink
buffer is readable (as we just registered a sink as writable).
-rw-r--r--lib/dtas/player.rb2
-rw-r--r--lib/dtas/unix_server.rb7
2 files changed, 8 insertions, 1 deletions
diff --git a/lib/dtas/player.rb b/lib/dtas/player.rb
index 04c03b0..f935d4c 100644
--- a/lib/dtas/player.rb
+++ b/lib/dtas/player.rb
@@ -312,7 +312,7 @@ class DTAS::Player # :nodoc:
     case rv = buf.broadcast(targets)
     when Array # array of blocked sinks
       # have sinks wake up the this buffer when they're writable
-      trade_ctl = proc { @srv.wait_ctl(buf, :wait_readable) }
+      trade_ctl = proc { @srv.wait_ctl(buf, :hot_read) }
       rv.each do |dst|
         dst.on_writable = trade_ctl
         @srv.wait_ctl(dst, :wait_writable)
diff --git a/lib/dtas/unix_server.rb b/lib/dtas/unix_server.rb
index 3931239..49437f3 100644
--- a/lib/dtas/unix_server.rb
+++ b/lib/dtas/unix_server.rb
@@ -69,6 +69,11 @@ class DTAS::UNIXServer # :nodoc:
 
   def wait_ctl(io, err)
     case err
+    when :hot_read
+      # this is only safe when we're iterating through ready writers
+      # the linear search for Array#include? is not expensive since
+      # we usually don't have a lot of sinks.
+      @hot_read << io unless @hot_read.include?(io)
     when :wait_readable
       @readers[io] = true
     when :wait_writable
@@ -95,10 +100,12 @@ class DTAS::UNIXServer # :nodoc:
   def run_once
     # give IO.select one-shot behavior, snapshot and replace the watchlist
     r = IO.select(@readers.keys, @writers.keys) or return
+    @hot_read = r[0]
     r[1].each do |io|
       @writers.delete(io)
       wait_ctl(io, io.writable_iter)
     end
+    @hot_read = nil
     r[0].each do |io|
       @readers.delete(io)
       wait_ctl(io, io.readable_iter { |_io, msg| yield(_io, msg) })