diff options
author | Eric Wong <normalperson@yhbt.net> | 2009-12-21 16:31:28 -0800 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2009-12-21 16:31:28 -0800 |
commit | ee7fe220ccbc991e1e7cbe982caf48e3303274c7 (patch) | |
tree | 8e735cac5a514ae0d48a877dc62c68b68a5506dc /lib | |
parent | e962d665c1e27de8d930c3acc51502fa4d147532 (diff) | |
download | rainbows-ee7fe220ccbc991e1e7cbe982caf48e3303274c7.tar.gz |
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.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/rainbows/base.rb | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/lib/rainbows/base.rb b/lib/rainbows/base.rb index 211b41c..4a4d076 100644 --- a/lib/rainbows/base.rb +++ b/lib/rainbows/base.rb @@ -14,6 +14,12 @@ module Rainbows super(worker) G.tmp = worker.tmp + # avoid spurious wakeups and blocking-accept() with 1.8 green threads + if RUBY_VERSION.to_f < 1.8 + require "io/nonblock" + LISTENERS.each { |l| l.nonblock = true } + end + # we're don't use the self-pipe mechanism in the Rainbows! worker # since we don't defer reopening logs HttpServer::SELF_PIPE.each { |x| x.close }.clear |