diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/rainbows/thread_spawn.rb | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/lib/rainbows/thread_spawn.rb b/lib/rainbows/thread_spawn.rb index 73a4107..40b37aa 100644 --- a/lib/rainbows/thread_spawn.rb +++ b/lib/rainbows/thread_spawn.rb @@ -25,35 +25,31 @@ module Rainbows limit = worker_connections begin - ret = begin - G.tick or break - IO.select(LISTENERS, nil, nil, 1) or next - rescue Errno::EINTR - retry - rescue Errno::EBADF, TypeError - break - end - G.tick - - ret.first.each do |l| - # Sleep if we're busy, another less busy worker process may - # take it for us if we sleep. This is gross but other options - # still suck because they require expensive/complicated - # synchronization primitives for _every_ case, not just this - # unlikely one. Since this case is (or should be) uncommon, - # just busy wait when we have to. - while threads.list.size > limit # unlikely - sleep(0.1) # hope another process took it - break # back to IO.select - end - begin - threads.add(Thread.new(l.accept_nonblock) {|c| process_client(c) }) - rescue Errno::EAGAIN, Errno::ECONNABORTED + ret = IO.select(LISTENERS, nil, nil, 1) and + ret.first.each do |l| + if threads.list.size > limit # unlikely + # Sleep if we're busy, another less busy worker process may + # take it for us if we sleep. This is gross but other options + # still suck because they require expensive/complicated + # synchronization primitives for _every_ case, not just this + # unlikely one. Since this case is (or should be) uncommon, + # just busy wait when we have to. + sleep(0.1) # hope another process took it + break # back to IO.select + end + c = begin + l.accept_nonblock + rescue Errno::EAGAIN, Errno::ECONNABORTED + end or next + threads.add(Thread.new { process_client(c) }) end - end + rescue Errno::EINTR + retry + rescue Errno::EBADF, TypeError + break rescue => e Error.listen_loop(e) - end while true + end while G.tick join_threads(threads.list) end |