From e64e2e0045d63c4edd291839febba978534be652 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sun, 8 May 2011 07:22:36 +0000 Subject: xepoll: cleanup acceptor logic worker_yield is safer than setting a threshold with multiple acceptors when thread limits are hit. Also, avoid sleep + Thread#run since it's potentially racy if threads are extremely unfairly scheduled. Same things applied to xepoll_thread_spawn. --- lib/rainbows/xepoll/client.rb | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/lib/rainbows/xepoll/client.rb b/lib/rainbows/xepoll/client.rb index 6cae2f1..c7eebcc 100644 --- a/lib/rainbows/xepoll/client.rb +++ b/lib/rainbows/xepoll/client.rb @@ -5,28 +5,30 @@ module Rainbows::XEpoll::Client N = Raindrops.new(1) Rainbows::Epoll.nr_clients = lambda { N[0] } include Rainbows::Epoll::Client - MAX = Rainbows.server.worker_connections - THRESH = MAX - 1 EP = Rainbows::Epoll::EP - THREADS = Rainbows::HttpServer::LISTENERS.map do |sock| - Thread.new do - sleep - begin - if io = sock.kgio_accept - N.incr(0, 1) - io.epoll_once - end - sleep while N[0] >= MAX - rescue => e - Rainbows::Error.listen_loop(e) - end while Rainbows.alive + ACCEPTORS = Rainbows::HttpServer::LISTENERS.dup + extend Rainbows::WorkerYield + + def self.included(klass) + max = Rainbows.server.worker_connections + ACCEPTORS.map! do |sock| + Thread.new do + begin + if io = sock.kgio_accept(klass) + N.incr(0, 1) + io.epoll_once + end + worker_yield while N[0] >= max + rescue => e + Rainbows::Error.listen_loop(e) + end while Rainbows.alive + end end end def self.run - THREADS.each { |t| t.run } Rainbows::Epoll.loop - Rainbows::JoinThreads.acceptors(THREADS) + Rainbows::JoinThreads.acceptors(ACCEPTORS) end # only call this once @@ -40,6 +42,6 @@ module Rainbows::XEpoll::Client def on_close KATO.delete(self) - N.decr(0, 1) == THRESH and THREADS.each { |t| t.run } + N.decr(0, 1) end end -- cgit v1.2.3-24-ge0c7