about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-01-21 13:21:07 -0800
committerEric Wong <normalperson@yhbt.net>2011-01-21 16:54:02 -0800
commit247ce76b4aabfa42157b9cbf9ebae824819cfff6 (patch)
treeb3c61036f7befb1d9cb697193dc8a629ac362fe7 /lib
parentb33ab73a984660ab2d741b32725ab21d7860bef3 (diff)
downloadrainbows-247ce76b4aabfa42157b9cbf9ebae824819cfff6.tar.gz
We can eliminate the State module to simplify our code
since 1.3.x keeps better track of things.
Diffstat (limited to 'lib')
-rw-r--r--lib/rainbows/epoll.rb10
-rw-r--r--lib/rainbows/epoll/client.rb20
-rw-r--r--lib/rainbows/epoll/response_pipe.rb7
-rw-r--r--lib/rainbows/epoll/server.rb14
-rw-r--r--lib/rainbows/epoll/state.rb22
5 files changed, 24 insertions, 49 deletions
diff --git a/lib/rainbows/epoll.rb b/lib/rainbows/epoll.rb
index 2f1d4a7..39c3a27 100644
--- a/lib/rainbows/epoll.rb
+++ b/lib/rainbows/epoll.rb
@@ -7,16 +7,20 @@ require 'sendfile'
 # and optimized for throughput at the expense of fairness
 module Rainbows::Epoll
   include Rainbows::Base
-  autoload :State, 'rainbows/epoll/state'
   autoload :Server, 'rainbows/epoll/server'
   autoload :Client, 'rainbows/epoll/client'
   autoload :ResponsePipe, 'rainbows/epoll/response_pipe'
   autoload :ResponseChunkPipe, 'rainbows/epoll/response_chunk_pipe'
 
+  def init_worker_process(worker)
+    super
+    Rainbows::Epoll.const_set :EP, SleepyPenguin::Epoll.new
+    trap(:QUIT) { Rainbows.quit!; EP.close unless EP.closed? }
+    Rainbows::Client.__send__ :include, Client
+  end
+
   def worker_loop(worker) # :nodoc:
     init_worker_process(worker)
-    trap(:QUIT) { Rainbows.quit!; State::EP.close unless State::EP.closed? }
-    Rainbows::Client.__send__ :include, Client
     Server.run
   end
 end
diff --git a/lib/rainbows/epoll/client.rb b/lib/rainbows/epoll/client.rb
index 334baa3..cb7097d 100644
--- a/lib/rainbows/epoll/client.rb
+++ b/lib/rainbows/epoll/client.rb
@@ -2,9 +2,7 @@
 # :enddoc:
 
 module Rainbows::Epoll::Client
-  attr_reader :wr_queue, :state, :epoll_active
 
-  include Rainbows::Epoll::State
   include Rainbows::EvCore
   APP = Rainbows.server.app
   Server = Rainbows::Epoll::Server
@@ -14,6 +12,7 @@ module Rainbows::Epoll::Client
   KATO = {}
   KATO.compare_by_identity if KATO.respond_to?(:compare_by_identity)
   KEEPALIVE_TIMEOUT = Rainbows.keepalive_timeout
+  EP = Rainbows::Epoll::EP
 
   def self.expire
     if (ot = KEEPALIVE_TIMEOUT) >= 0
@@ -25,7 +24,6 @@ module Rainbows::Epoll::Client
   # only call this once
   def epoll_once
     @wr_queue = [] # may contain String, ResponsePipe, and StreamFile objects
-    @epoll_active = false
     post_init
     epoll_run
     rescue => e
@@ -39,7 +37,7 @@ module Rainbows::Epoll::Client
       return if @wr_queue[0] || closed?
     when :wait_readable
       KATO[self] = Time.now if :headers == @state
-      return epoll_enable(IN)
+      return EP.set(self, IN)
     else
       break
     end until :close == @state
@@ -130,7 +128,7 @@ module Rainbows::Epoll::Client
       obj = rv # retry
     when :wait_writable # Strings and StreamFiles only
       @wr_queue.unshift(obj)
-      epoll_enable(OUT)
+      EP.set(self, OUT)
       return
     when :deferred
       return
@@ -148,7 +146,7 @@ module Rainbows::Epoll::Client
       when String
         buf = rv # retry
       when :wait_writable
-        epoll_enable(OUT)
+        EP.set(self, OUT)
         break # queue
       end while true
     end
@@ -197,7 +195,7 @@ module Rainbows::Epoll::Client
       stream_file(sf) or return
     end
     @wr_queue << sf
-    epoll_enable(OUT)
+    EP.set(self, OUT)
   end
 
   # this alternates between a push and pull model from the pipe -> client
@@ -207,16 +205,16 @@ module Rainbows::Epoll::Client
     when String
       if Array === write(buf)
         # client is blocked on write, client will pull from pipe later
-        pipe.epoll_disable
+        EP.delete pipe
         @wr_queue << pipe
-        epoll_enable(OUT)
+        EP.set(self, OUT)
         return :deferred
       end
       # continue looping...
     when :wait_readable
       # pipe blocked on read, let the pipe push to the client in the future
-      epoll_disable
-      pipe.epoll_enable(IN)
+      EP.delete self
+      EP.set(pipe, IN)
       return :deferred
     else # nil => EOF
       return pipe.close # nil
diff --git a/lib/rainbows/epoll/response_pipe.rb b/lib/rainbows/epoll/response_pipe.rb
index ce240f5..08731b1 100644
--- a/lib/rainbows/epoll/response_pipe.rb
+++ b/lib/rainbows/epoll/response_pipe.rb
@@ -2,15 +2,13 @@
 # :enddoc:
 #
 class Rainbows::Epoll::ResponsePipe
-  include Rainbows::Epoll::State
   attr_reader :io
   alias to_io io
-  IN = SleepyPenguin::Epoll::IN | SleepyPenguin::Epoll::ET
   RBUF = Rainbows::EvCore::RBUF
+  EP = Rainbows::Epoll::EP
 
   def initialize(io, client, body)
     @io, @client, @body = io, client, body
-    @epoll_active = false
   end
 
   def epoll_run
@@ -22,7 +20,8 @@ class Rainbows::Epoll::ResponsePipe
   end
 
   def close
-    epoll_disable
+    @io or return
+    EP.delete self
     @body.respond_to?(:close) and @body.close
     @io = @body = nil
   end
diff --git a/lib/rainbows/epoll/server.rb b/lib/rainbows/epoll/server.rb
index 1f61662..53b87ab 100644
--- a/lib/rainbows/epoll/server.rb
+++ b/lib/rainbows/epoll/server.rb
@@ -5,16 +5,12 @@ module Rainbows::Epoll::Server
   @@nr = 0
   MAX = Rainbows.server.worker_connections
   THRESH = MAX - 1
-  include Rainbows::Epoll::State
   LISTENERS = Rainbows::HttpServer::LISTENERS
   ReRun = []
-
-  def self.extended(obj)
-    obj.instance_variable_set(:@epoll_active, false)
-  end
+  EP = Rainbows::Epoll::EP
 
   def self.run
-    LISTENERS.each { |sock| sock.extend(self).epoll_enable(IN) }
+    LISTENERS.each { |sock| EP.add(sock.extend(self), IN) }
     begin
       EP.wait(nil, 1000) { |_, obj| obj.epoll_run }
       while obj = ReRun.shift
@@ -28,16 +24,16 @@ module Rainbows::Epoll::Server
 
   # rearms all listeners when there's a free slot
   def self.decr
-    THRESH == (@@nr -= 1) and LISTENERS.each { |sock| sock.epoll_enable(IN) }
+    THRESH == (@@nr -= 1) and LISTENERS.each { |sock| EP.set(sock, IN) }
   end
 
   def epoll_run
-    return epoll_disable if @@nr >= MAX
+    return EP.delete(self) if @@nr >= MAX
     while io = kgio_tryaccept
       @@nr += 1
       # there's a chance the client never even sees epoll for simple apps
       io.epoll_once
-      return epoll_disable if @@nr >= MAX
+      return EP.delete(self) if @@nr >= MAX
     end
   end
 end
diff --git a/lib/rainbows/epoll/state.rb b/lib/rainbows/epoll/state.rb
deleted file mode 100644
index 6e554be..0000000
--- a/lib/rainbows/epoll/state.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- encoding: binary -*-
-# :enddoc:
-# used to keep track of state for each descriptor and avoid
-# unneeded syscall or ENONENT overhead
-module Rainbows::Epoll::State
-  EP = SleepyPenguin::Epoll.new
-
-  def epoll_disable
-    @epoll_active or return
-    @epoll_active = false
-    EP.del(self)
-  end
-
-  def epoll_enable(flags)
-    if @epoll_active
-      flags == @epoll_active or
-        EP.mod(self, @epoll_active = flags)
-    else
-      EP.add(self, @epoll_active = flags)
-    end
-  end
-end