diff options
author | Eric Wong <normalperson@yhbt.net> | 2010-03-01 10:29:01 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2010-03-01 10:29:01 +0000 |
commit | 7dde8d1402a44e2997fa86ff5e3cf89c4ca6d82a (patch) | |
tree | 47c38ac71b65068c845481b2efe1e37d3adfbcdb | |
parent | 168bacbea266baecafe72adc1d7fa08674607744 (diff) | |
download | zbatery-7dde8d1402a44e2997fa86ff5e3cf89c4ca6d82a.tar.gz |
MRI 1.8 thread fix to avoid blocking accept()
Rainbows! commit ee7fe220ccbc991e1e7cbe982caf48e3303274c7 Under MRI 1.8, listen sockets do not appear to have the nonblocking I/O flag on by default, nor does it set the nonblocking I/O flag when calling #accept (but it does when using #accept_nonblock, of course). Normally this is not a problem even when using green threads since MRI will internally select(2) on the file descriptor before attempting a blocking (and immediately successful) accept(2). However, when sharing a listen descriptor across multiple processes, spurious wakeups are likely to occur, causing multiple processes may be woken up when a single client connects. This causes a problem because accept(2)-ing on multiple threads/processes for a single connection causes blocking accepts in multiple processes, leading to stalled green threads. This is not an issue under 1.9 where a blocking accept() call unlocks the GVL to let other threads run.
-rw-r--r-- | lib/zbatery.rb | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/lib/zbatery.rb b/lib/zbatery.rb index ce542d6..b2eb7ad 100644 --- a/lib/zbatery.rb +++ b/lib/zbatery.rb @@ -127,6 +127,13 @@ module Rainbows after_fork.call(self, worker) worker.user(*user) if user.kind_of?(Array) && ! worker.switched build_app! unless preload_app + + # avoid spurious wakeups and blocking-accept() with 1.8 green threads + if RUBY_VERSION.to_f < 1.9 + require "io/nonblock" + HttpServer::LISTENERS.each { |l| l.nonblock = true } + end + logger.info "Zbatery #@use worker_connections=#@worker_connections" end end |