From 247ce76b4aabfa42157b9cbf9ebae824819cfff6 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 21 Jan 2011 13:21:07 -0800 Subject: epoll: use newer sleepy_penguin We can eliminate the State module to simplify our code since 1.3.x keeps better track of things. --- lib/rainbows/epoll.rb | 10 +++++++--- lib/rainbows/epoll/client.rb | 20 +++++++++----------- lib/rainbows/epoll/response_pipe.rb | 7 +++---- lib/rainbows/epoll/server.rb | 14 +++++--------- lib/rainbows/epoll/state.rb | 22 ---------------------- 5 files changed, 24 insertions(+), 49 deletions(-) delete mode 100644 lib/rainbows/epoll/state.rb (limited to 'lib') 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 -- cgit v1.2.3-24-ge0c7