about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-05-08 04:06:12 +0000
committerEric Wong <normalperson@yhbt.net>2011-05-08 05:24:23 +0000
commit07a0bee9dd6f2c366d11284b7e9ab09d66b411e4 (patch)
tree00c20d3199c2bb36d643b021d3789bd19f89b979
parentc543b295ff2108623f3748a141e04e5530d06377 (diff)
downloadrainbows-07a0bee9dd6f2c366d11284b7e9ab09d66b411e4.tar.gz
Infinite sleep is too dangerous due to possible race conditions,
so use worker_yield which is safer and cheaper in the general
case.  We can also avoid sleeping on new threads by only
spawning when the client module is included.
-rw-r--r--lib/rainbows/xepoll_thread_spawn/client.rb36
1 files changed, 19 insertions, 17 deletions
diff --git a/lib/rainbows/xepoll_thread_spawn/client.rb b/lib/rainbows/xepoll_thread_spawn/client.rb
index 1ed0de8..72031eb 100644
--- a/lib/rainbows/xepoll_thread_spawn/client.rb
+++ b/lib/rainbows/xepoll_thread_spawn/client.rb
@@ -2,27 +2,30 @@
 module Rainbows::XEpollThreadSpawn::Client
   HBUFSIZ = Rainbows.client_header_buffer_size
   N = Raindrops.new(1)
-  max = Rainbows.server.worker_connections
-  ACCEPTORS = Rainbows::HttpServer::LISTENERS.map do |sock|
-    Thread.new do
-      sleep
-      buf = ""
-      begin
-        if io = sock.kgio_accept(Rainbows::Client)
-          N.incr(0, 1)
-          io.epoll_once(buf)
-        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) # included in Rainbows::Client
+    max = Rainbows.server.worker_connections
+    ACCEPTORS.map! do |sock|
+      Thread.new do
+        buf = ""
+        begin
+          if io = sock.kgio_accept(klass)
+            N.incr(0, 1)
+            io.epoll_once(buf)
+          end
+          worker_yield while N[0] >= max
+        rescue => e
+          Rainbows::Error.listen_loop(e)
+        end while Rainbows.alive
+      end
     end
   end
 
   ep = SleepyPenguin::Epoll
   EP = ep.new
   IN = ep::IN | ep::ET | ep::ONESHOT
-  THRESH = max - 1
   KATO = {}
   KATO.compare_by_identity if KATO.respond_to?(:compare_by_identity)
   LOCK = Mutex.new
@@ -38,7 +41,6 @@ module Rainbows::XEpollThreadSpawn::Client
   end
 
   def self.loop
-    ACCEPTORS.each { |thr| thr.run }
     buf = ""
     begin
       EP.wait(nil, 1000) { |fl, obj| obj.epoll_run(buf) }
@@ -71,7 +73,7 @@ module Rainbows::XEpollThreadSpawn::Client
   def close
     super
     kato_delete
-    N.decr(0, 1) == THRESH and ACCEPTORS.each { |t| t.run }
+    N.decr(0, 1)
     nil
   end