about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-12-04 22:49:29 +0000
committerEric Wong <e@80x24.org>2015-12-08 05:13:28 +0000
commitb0cb2bb41e76c4c3bfedd87f49e5ff70e9b830e2 (patch)
tree9fe7e8181ea96596fea7e17914b4080d49810270
parentf6fc3ac41d8e43dfb8558be88ca4de9f6c856dd5 (diff)
downloadyahns-opt-case.tar.gz
Ruby-trunk (as of r52931) optimizes case dispatch for additional
immediate values such as `nil', `true', and `false'.

Rearrange our case statements (and take away some safety-checks
:x) to take advantage of these optimizations in ruby-trunk.

ref:
https://bugs.ruby-lang.org/issues/11769
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/71818
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/71825
-rw-r--r--extras/proxy_pass.rb2
-rw-r--r--lib/yahns/http_client.rb34
-rw-r--r--lib/yahns/http_response.rb26
-rw-r--r--lib/yahns/proxy_http_response.rb50
-rw-r--r--lib/yahns/sendfile_compat.rb6
-rw-r--r--lib/yahns/wbuf.rb4
-rw-r--r--lib/yahns/wbuf_str.rb4
-rw-r--r--lib/yahns/worker.rb10
8 files changed, 67 insertions, 69 deletions
diff --git a/extras/proxy_pass.rb b/extras/proxy_pass.rb
index 29dd995..bfe3b8f 100644
--- a/extras/proxy_pass.rb
+++ b/extras/proxy_pass.rb
@@ -61,7 +61,7 @@ class ProxyPass # :nodoc:
         kgio_wait_writable(wait_time)
       when nil
         return
-      when String
+      else # String
         buf = rv
       end while true
     end
diff --git a/lib/yahns/http_client.rb b/lib/yahns/http_client.rb
index db53587..117300e 100644
--- a/lib/yahns/http_client.rb
+++ b/lib/yahns/http_client.rb
@@ -28,15 +28,13 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc:
     when :ignore # :ignore on hijack
       @state = :ignore
       return :ignore
-    when Yahns::StreamFile
-      @state = rv # continue looping
     when true, false # done
       return http_response_done(rv)
     when :ccc_done, :r100_done
       @state = rv
       return :wait_writable
-    else
-      raise "BUG: #{@state.inspect}#wbuf_flush returned #{rv.inspect}"
+    else # Yahns::StreamFile
+      @state = rv # continue looping
     end while true
   end
 
@@ -79,14 +77,14 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc:
   # returns :wait_readable/wait_writable/nil to yield back to epoll
   def fill_body(rsize, rbuf)
     case rv = kgio_tryread(rsize, rbuf)
-    when String
-      @hs.filter_body(rbuf, @hs.buf << rbuf)
-      @input.write(rbuf)
-      true # keep looping on kgio_tryread (but check body_eof? first)
     when :wait_readable, :wait_writable
       rv # have epoll/kqueue wait for more
     when nil # unexpected EOF
       @input.close # nil
+    else # String
+      @hs.filter_body(rbuf, @hs.buf << rbuf)
+      @input.write(rbuf)
+      true # keep looping on kgio_tryread (but check body_eof? first)
     end
   end
 
@@ -94,16 +92,16 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc:
   # returns :wait_readable/wait_writable/nil to yield back to epoll
   def read_trailers(rsize, rbuf)
     case rv = kgio_tryread(rsize, rbuf)
-    when String
+    when :wait_readable, :wait_writable
+      return rv # wait for more
+    when nil # unexpected EOF
+      return @input.close # nil
+    else # String
       if @hs.add_parse(rbuf)
         @input.rewind
         return true
       end
       # keep looping on kgio_tryread...
-    when :wait_readable, :wait_writable
-      return rv # wait for more
-    when nil # unexpected EOF
-      return @input.close # nil
     end while true
   end
 
@@ -132,7 +130,9 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc:
       # continue to outer loop
     when :headers
       case rv = kgio_tryread(k.client_header_buffer_size, rbuf)
-      when String
+      when :wait_readable, :wait_writable, nil
+        return rv
+      else # String
         if @hs.add_parse(rv)
           case input = input_ready
           when :wait_readable, :wait_writable, :close then return input
@@ -142,8 +142,6 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc:
           end
         end
         # keep looping on kgio_tryread
-      when :wait_readable, :wait_writable, nil
-        return rv
       end while true
     when :body
       if @hs.body_eof?
@@ -234,12 +232,12 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc:
   # used by StreamInput (and thus TeeInput) for input_buffering {false|:lazy}
   def yahns_read(bytes, buf)
     case rv = kgio_tryread(bytes, buf)
-    when String, nil
-      return rv
     when :wait_readable
       kgio_wait_readable or raise Yahns::ClientTimeout, "waiting for read", []
     when :wait_writable
       kgio_wait_writable or raise Yahns::ClientTimeout, "waiting for write", []
+    else # String, nil
+      return rv
     end while true
   end
 
diff --git a/lib/yahns/http_response.rb b/lib/yahns/http_response.rb
index 99bf664..cbfcf77 100644
--- a/lib/yahns/http_response.rb
+++ b/lib/yahns/http_response.rb
@@ -75,11 +75,11 @@ module Yahns::HttpResponse # :nodoc:
       case rv = wbuf.wbuf_close(self)
       when :ignore # hijacked
         @state = rv
-      when Yahns::StreamFile
-        @state = rv
-        :wait_writable
       when true, false
         http_response_done(rv)
+      else # Yahns::StreamFile
+        @state = rv
+        :wait_writable
       end
     else
       @state = wbuf
@@ -162,9 +162,6 @@ module Yahns::HttpResponse # :nodoc:
       case rv = kgio_syssend(buf, flags)
       when nil # all done, likely
         break
-      when String
-        flags = MSG_DONTWAIT
-        buf = rv # hope the skb grows
       when :wait_writable, :wait_readable
         if k.output_buffering
           alive = hijack ? hijack : alive
@@ -174,6 +171,9 @@ module Yahns::HttpResponse # :nodoc:
         else
           response_wait_write(rv) or return :close
         end
+      else # String
+        flags = MSG_DONTWAIT
+        buf = rv # hope the skb grows
       end while true
     end
 
@@ -192,8 +192,6 @@ module Yahns::HttpResponse # :nodoc:
         case rv = kgio_trywrite(chunk)
         when nil # all done, likely and good!
           break
-        when String
-          chunk = rv # hope the skb grows when we loop into the trywrite
         when :wait_writable, :wait_readable
           if k.output_buffering
             wbuf = Yahns::Wbuf.new(body, alive, k.output_buffer_tmpdir, rv)
@@ -202,6 +200,8 @@ module Yahns::HttpResponse # :nodoc:
           else
             response_wait_write(rv) or return :close
           end
+        else # String
+          chunk = rv # hope the skb grows when we loop into the trywrite
         end while true
       end
     end
@@ -231,8 +231,6 @@ module Yahns::HttpResponse # :nodoc:
         case rv = kgio_trywrite(buf)
         when nil
           break
-        when String
-          buf = rv
         when :wait_writable, :wait_readable
           if self.class.output_buffering
             wbuf = buf.dup
@@ -241,6 +239,8 @@ module Yahns::HttpResponse # :nodoc:
           else
             response_wait_write(rv) or return :close
           end
+        else # String
+          buf = rv
         end while true
       end
     end
@@ -257,8 +257,6 @@ module Yahns::HttpResponse # :nodoc:
                                   : "HTTP/1.1 100 Continue\r\n\r\n".freeze
 
     case rv = kgio_trywrite(buf)
-    when String
-      buf = rv
     when :wait_writable, :wait_readable
       if self.class.output_buffering
         @state = Yahns::WbufStr.new(buf, :r100_done)
@@ -266,8 +264,10 @@ module Yahns::HttpResponse # :nodoc:
       else
         response_wait_write(rv) or return :close
       end
-    else
+    when nil
       return rv
+    else # String
+      buf = rv
     end while true
   end
 end
diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb
index 3858456..13f8870 100644
--- a/lib/yahns/proxy_http_response.rb
+++ b/lib/yahns/proxy_http_response.rb
@@ -13,12 +13,12 @@ module Yahns::HttpResponse # :nodoc:
       # no write buffer, try to write directly to the client socket
       case rv = String === buf ? kgio_trywrite(buf) : kgio_trywritev(buf)
       when nil then return # done writing buf, likely
-      when String, Array # partial write, hope the skb grows
-        buf = rv
       when :wait_writable, :wait_readable
         wbuf = Yahns::Wbuf.new(nil, alive, self.class.output_buffer_tmpdir, rv)
         buf = buf.join if Array === buf
         break
+      else # String, Array # partial write, hope the skb grows
+        buf = rv
       end while true
     end
 
@@ -97,12 +97,12 @@ module Yahns::HttpResponse # :nodoc:
     # send the headers
     case rv = kgio_syssend(res, flags)
     when nil then break # all done, likely
-    when String # partial write, highly unlikely
-      flags = MSG_DONTWAIT
-      res = rv # hope the skb grows
     when :wait_writable, :wait_readable # highly unlikely in real apps
       wbuf = proxy_write(nil, res, alive)
       break # keep buffering as much as possible
+    else # String # partial write, highly unlikely
+      flags = MSG_DONTWAIT
+      res = rv # hope the skb grows
     end while true
 
     rbuf = Thread.current[:yahns_rbuf]
@@ -112,26 +112,26 @@ module Yahns::HttpResponse # :nodoc:
       if len = kcar.body_bytes_left
 
         case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf)
-        when String
-          len = kcar.body_bytes_left -= tmp.size
-          wbuf = proxy_write(wbuf, tmp, alive)
         when nil # premature EOF
           return proxy_err_response(nil, req_res, nil, wbuf)
         when :wait_readable
           return wait_on_upstream(req_res, alive, wbuf)
+        else # String
+          len = kcar.body_bytes_left -= tmp.size
+          wbuf = proxy_write(wbuf, tmp, alive)
         end until len == 0
 
       elsif kcar.chunked? # nasty chunked body
         req_res.proxy_trailers = nil # define to avoid warnings for now
         buf = ''
         case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf)
-        when String
-          kcar.filter_body(buf, tmp)
-          wbuf = proxy_write(wbuf, chunk_out(buf), alive) unless buf.empty?
         when nil # premature EOF
           return proxy_err_response(nil, req_res, nil, wbuf)
         when :wait_readable
           return wait_on_upstream(req_res, alive, wbuf)
+        else # String
+          kcar.filter_body(buf, tmp)
+          wbuf = proxy_write(wbuf, chunk_out(buf), alive) unless buf.empty?
         end until kcar.body_eof?
 
         buf = tmp
@@ -139,12 +139,12 @@ module Yahns::HttpResponse # :nodoc:
         rbuf = Thread.current[:yahns_rbuf] = ''
         until kcar.trailers(tlr, buf)
           case rv = req_res.kgio_tryread(0x2000, rbuf)
-          when String
-            buf << rv
           when :wait_readable
             return wait_on_upstream(req_res, alive, wbuf)
           when nil # premature EOF
             return proxy_err_response(nil, req_res, nil, wbuf)
+          else # String
+            buf << rv
           end # no loop here
         end
         wbuf = proxy_write(wbuf, trailer_out(tlr), alive)
@@ -152,13 +152,13 @@ module Yahns::HttpResponse # :nodoc:
       else # no Content-Length or Transfer-Encoding: chunked, wait on EOF!
 
         case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf)
-        when String
-          wbuf = proxy_write(wbuf, tmp, alive)
         when nil
           req_res.shutdown
           break
         when :wait_readable
           return wait_on_upstream(req_res, alive, wbuf)
+        else # String
+          wbuf = proxy_write(wbuf, tmp, alive)
         end while true
 
       end
@@ -176,13 +176,13 @@ module Yahns::HttpResponse # :nodoc:
     if len = kcar.body_bytes_left
 
       case tmp = req_res.kgio_tryread(0x2000, rbuf)
-      when String
-        len = kcar.body_bytes_left -= tmp.size
-        wbuf.wbuf_write(self, tmp)
       when nil # premature EOF
         return proxy_err_response(nil, req_res, nil, wbuf)
       when :wait_readable
         return :wait_readable # self remains in :ignore, wait on upstream
+      else # String
+        len = kcar.body_bytes_left -= tmp.size
+        wbuf.wbuf_write(self, tmp)
       end while len != 0
 
     elsif kcar.chunked? # nasty chunked body
@@ -191,13 +191,13 @@ module Yahns::HttpResponse # :nodoc:
       unless req_res.proxy_trailers
         # are we done dechunking the main body, yet?
         case tmp = req_res.kgio_tryread(0x2000, rbuf)
-        when String
-          kcar.filter_body(buf, tmp)
-          buf.empty? or wbuf.wbuf_write(self, chunk_out(buf))
         when nil # premature EOF
           return proxy_err_response(nil, req_res, nil, wbuf)
         when :wait_readable
           return :wait_readable # self remains in :ignore, wait on upstream
+        else # String
+          kcar.filter_body(buf, tmp)
+          buf.empty? or wbuf.wbuf_write(self, chunk_out(buf))
         end until kcar.body_eof?
         req_res.proxy_trailers = [ tmp, [] ] # onto trailers!
         rbuf = Thread.current[:yahns_rbuf] = ''
@@ -206,12 +206,12 @@ module Yahns::HttpResponse # :nodoc:
       buf, tlr = *req_res.proxy_trailers
       until kcar.trailers(tlr, buf)
         case rv = req_res.kgio_tryread(0x2000, rbuf)
-        when String
-          buf << rv
         when :wait_readable
           return :wait_readable
         when nil # premature EOF
           return proxy_err_response(nil, req_res, nil, wbuf)
+        else # String
+          buf << rv
         end # no loop here
       end
       wbuf.wbuf_write(self, trailer_out(tlr))
@@ -219,13 +219,13 @@ module Yahns::HttpResponse # :nodoc:
     else # no Content-Length or Transfer-Encoding: chunked, wait on EOF!
 
       case tmp = req_res.kgio_tryread(0x2000, rbuf)
-      when String
-        wbuf.wbuf_write(self, tmp)
       when nil
         req_res.shutdown
         break
       when :wait_readable
         return :wait_readable # self remains in :ignore, wait on upstream
+      else # String
+        wbuf.wbuf_write(self, tmp)
       end while true
 
     end
diff --git a/lib/yahns/sendfile_compat.rb b/lib/yahns/sendfile_compat.rb
index da2a9ec..6d4cc56 100644
--- a/lib/yahns/sendfile_compat.rb
+++ b/lib/yahns/sendfile_compat.rb
@@ -11,13 +11,13 @@ module Yahns::SendfileCompat
     str = io.read(count, buf) or return # nil for EOF
     n = 0
     case rv = kgio_trywrite(str)
-    when String # partial write, keep trying
-      n += (str.size - rv.size)
-      str = rv
     when :wait_writable, :wait_readable
       return n > 0 ? n : rv
     when nil
       return n + str.size # yay!
+    else # String # partial write, keep trying
+      n += (str.size - rv.size)
+      str = rv
     end while true
   end
 end
diff --git a/lib/yahns/wbuf.rb b/lib/yahns/wbuf.rb
index 1a24aab..f857a60 100644
--- a/lib/yahns/wbuf.rb
+++ b/lib/yahns/wbuf.rb
@@ -50,12 +50,12 @@ class Yahns::Wbuf # :nodoc:
     # try to bypass the VFS layer and write directly to the socket
     # if we're all caught up
     case rv = String === buf ? c.kgio_trywrite(buf) : c.kgio_trywritev(buf)
-    when String, Array
-      buf = rv # retry in loop
     when nil
       return # yay! hopefully we don't have to buffer again
     when :wait_writable, :wait_readable
       @busy = rv
+    else # String, Array
+      buf = rv # retry in loop
     end until @busy
 
     @tmpio ||= Yahns::TmpIO.new(@tmpdir)
diff --git a/lib/yahns/wbuf_str.rb b/lib/yahns/wbuf_str.rb
index 89dfd33..a997a76 100644
--- a/lib/yahns/wbuf_str.rb
+++ b/lib/yahns/wbuf_str.rb
@@ -27,12 +27,12 @@ class Yahns::WbufStr # :nodoc:
 
   def wbuf_flush(client)
     case rv = client.kgio_trywrite(@str)
-    when String
-      @str = rv
     when :wait_writable, :wait_readable
       return rv
     when nil
       return @next
+    else # String
+      @str = rv
     end while true
   end
 end
diff --git a/lib/yahns/worker.rb b/lib/yahns/worker.rb
index d6e7364..aceaf4e 100644
--- a/lib/yahns/worker.rb
+++ b/lib/yahns/worker.rb
@@ -24,17 +24,17 @@ class Yahns::Worker # :nodoc:
   # dies unexpectedly.
   def yahns_step
     case buf = @to_io.kgio_tryread(4)
-    when String
-      # unpack the buffer and trigger the signal handler
-      signum = buf.unpack('l')
-      fake_sig(signum[0])
-      # keep looping, more signals may be queued
     when nil # EOF: master died, but we are at a safe place to exit
       fake_sig(:QUIT)
       @to_io.close
       return :ignore
     when :wait_readable # keep waiting
       return :ignore
+    else # String
+      # unpack the buffer and trigger the signal handler
+      signum = buf.unpack('l')
+      fake_sig(signum[0])
+      # keep looping, more signals may be queued
     end while true # loop, as multiple signals may be sent
   end