diff options
author | Eric Wong <normalperson@yhbt.net> | 2009-11-28 19:42:53 -0800 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2009-11-29 12:35:44 -0800 |
commit | 37a560c5d14c15a3da7f2c10c9ea3d6002b34fe1 (patch) | |
tree | 8d163646e4ba3586cafde788804c580e3315431c /lib/rainbows/thread_pool.rb | |
parent | 50fb5151bd44137adace51a0652f4d01d851790c (diff) | |
download | rainbows-37a560c5d14c15a3da7f2c10c9ea3d6002b34fe1.tar.gz |
It's a tad faster for non-keepalive connections and should do better on large SMP machines with many workers AND threads. That means the ActorSpawn model in Rubinius is nothing more than ThreadSpawn underneath (for now).
Diffstat (limited to 'lib/rainbows/thread_pool.rb')
-rw-r--r-- | lib/rainbows/thread_pool.rb | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/lib/rainbows/thread_pool.rb b/lib/rainbows/thread_pool.rb index f398828..917b835 100644 --- a/lib/rainbows/thread_pool.rb +++ b/lib/rainbows/thread_pool.rb @@ -27,39 +27,44 @@ module Rainbows def worker_loop(worker) init_worker_process(worker) - pool = (1..worker_connections).map { new_worker_thread } + pool = (1..worker_connections).map do + Thread.new { LISTENERS.size == 1 ? sync_worker : async_worker } + end while G.alive # if any worker dies, something is serious wrong, bail pool.each do |thr| - G.tick + G.tick or break thr.join(1) and G.quit! end end join_threads(pool) end - def new_worker_thread - Thread.new { - begin - begin - # TODO: check if select() or accept() is a problem on large - # SMP systems under Ruby 1.9. Hundreds of native threads - # all working off the same socket could be a thundering herd - # problem. On the other hand, a thundering herd may not - # even incur as much overhead as an extra Mutex#synchronize - ret = IO.select(LISTENERS, nil, nil, 1) and - ret.first.each do |s| - s = Rainbows.accept(s) and process_client(s) - end - rescue Errno::EINTR - rescue Errno::EBADF, TypeError - break - end - rescue => e - Error.listen_loop(e) - end while G.alive - } + def sync_worker + s = LISTENERS.first + begin + process_client(s.accept) + rescue Errno::EINTR, Errno::ECONNABORTED + rescue => e + Error.listen_loop(e) + end while G.alive + end + + def async_worker + begin + # TODO: check if select() or accept() is a problem on large + # SMP systems under Ruby 1.9. Hundreds of native threads + # all working off the same socket could be a thundering herd + # problem. On the other hand, a thundering herd may not + # even incur as much overhead as an extra Mutex#synchronize + ret = IO.select(LISTENERS, nil, nil, 1) and ret.first.each do |s| + s = Rainbows.accept(s) and process_client(s) + end + rescue Errno::EINTR + rescue => e + Error.listen_loop(e) + end while G.alive end end |