diff options
Diffstat (limited to 'lib/rainbows')
-rw-r--r-- | lib/rainbows/acceptor.rb | 26 | ||||
-rw-r--r-- | lib/rainbows/event_machine.rb | 3 | ||||
-rw-r--r-- | lib/rainbows/fiber/rev.rb | 3 | ||||
-rw-r--r-- | lib/rainbows/fiber_pool.rb | 3 | ||||
-rw-r--r-- | lib/rainbows/fiber_spawn.rb | 3 | ||||
-rw-r--r-- | lib/rainbows/rev/core.rb | 3 | ||||
-rw-r--r-- | lib/rainbows/thread_pool.rb | 5 | ||||
-rw-r--r-- | lib/rainbows/thread_spawn.rb | 3 |
8 files changed, 41 insertions, 8 deletions
diff --git a/lib/rainbows/acceptor.rb b/lib/rainbows/acceptor.rb new file mode 100644 index 0000000..c67bf20 --- /dev/null +++ b/lib/rainbows/acceptor.rb @@ -0,0 +1,26 @@ +# -*- encoding: binary -*- + +# :enddoc: +require 'fcntl' + +# this should make life easier for Zbatery if compatibility with +# fcntl-crippled platforms is required (or if FD_CLOEXEC is inherited) +# and we want to microptimize away fcntl(2) syscalls. +module Rainbows::Acceptor + + # returns nil if accept fails + def sync_accept(sock) + rv = sock.accept + rv.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) + rv + rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EINTR + end + + # returns nil if accept fails + def accept(sock) + rv = sock.accept_nonblock + rv.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) + rv + rescue Errno::EAGAIN, Errno::ECONNABORTED + end +end diff --git a/lib/rainbows/event_machine.rb b/lib/rainbows/event_machine.rb index a0b9ca6..2a41015 100644 --- a/lib/rainbows/event_machine.rb +++ b/lib/rainbows/event_machine.rb @@ -169,6 +169,7 @@ module Rainbows end module Server # :nodoc: all + include Rainbows::Acceptor def close detach @@ -177,7 +178,7 @@ module Rainbows def notify_readable return if CUR.size >= MAX - io = Rainbows.accept(@io) or return + io = accept(@io) or return sig = EM.attach_fd(io.fileno, false) CUR[sig] = CL.new(sig, io) end diff --git a/lib/rainbows/fiber/rev.rb b/lib/rainbows/fiber/rev.rb index c23d844..632b562 100644 --- a/lib/rainbows/fiber/rev.rb +++ b/lib/rainbows/fiber/rev.rb @@ -54,6 +54,7 @@ module Rainbows::Fiber include Rainbows include Rainbows::Const include Rainbows::Response + include Rainbows::Acceptor FIO = Rainbows::Fiber::IO def to_io @@ -72,7 +73,7 @@ module Rainbows::Fiber def on_readable return if G.cur >= MAX - c = Rainbows.accept(@io) and ::Fiber.new { process(c) }.resume + c = accept(@io) and ::Fiber.new { process(c) }.resume end def process(io) diff --git a/lib/rainbows/fiber_pool.rb b/lib/rainbows/fiber_pool.rb index 42f6dbe..63f1e2e 100644 --- a/lib/rainbows/fiber_pool.rb +++ b/lib/rainbows/fiber_pool.rb @@ -15,6 +15,7 @@ module Rainbows module FiberPool include Fiber::Base + include Rainbows::Acceptor def worker_loop(worker) # :nodoc: init_worker_process(worker) @@ -29,7 +30,7 @@ module Rainbows begin schedule do |l| fib = pool.shift or break # let another worker process take it - if io = Rainbows.accept(l) + if io = accept(l) fib.resume(Fiber::IO.new(io, fib)) else pool << fib diff --git a/lib/rainbows/fiber_spawn.rb b/lib/rainbows/fiber_spawn.rb index df72e70..ecf83d8 100644 --- a/lib/rainbows/fiber_spawn.rb +++ b/lib/rainbows/fiber_spawn.rb @@ -12,6 +12,7 @@ module Rainbows module FiberSpawn include Fiber::Base + include Rainbows::Acceptor def worker_loop(worker) # :nodoc: init_worker_process(worker) @@ -22,7 +23,7 @@ module Rainbows begin schedule do |l| break if G.cur >= limit - io = Rainbows.accept(l) or next + io = accept(l) or next ::Fiber.new { process_client(fio.new(io, ::Fiber.current)) }.resume end rescue => e diff --git a/lib/rainbows/rev/core.rb b/lib/rainbows/rev/core.rb index 9f7a1f0..9f20574 100644 --- a/lib/rainbows/rev/core.rb +++ b/lib/rainbows/rev/core.rb @@ -7,12 +7,13 @@ require 'rainbows/rev/heartbeat' module Rainbows module Rev class Server < ::Rev::IO + include Rainbows::Acceptor G = Rainbows::G # CL and MAX will be defined in the corresponding worker loop def on_readable return if CONN.size >= MAX - io = Rainbows.accept(@_io) and CL.new(io).attach(LOOP) + io = accept(@_io) and CL.new(io).attach(LOOP) end end # class Server diff --git a/lib/rainbows/thread_pool.rb b/lib/rainbows/thread_pool.rb index 28a943e..a643bd8 100644 --- a/lib/rainbows/thread_pool.rb +++ b/lib/rainbows/thread_pool.rb @@ -24,6 +24,7 @@ module Rainbows module ThreadPool include Base + include Rainbows::Acceptor def worker_loop(worker) # :nodoc: init_worker_process(worker) @@ -44,7 +45,7 @@ module Rainbows def sync_worker # :nodoc: s = LISTENERS[0] begin - c = Rainbows.sync_accept(s) and process_client(c) + c = sync_accept(s) and process_client(c) rescue => e Error.listen_loop(e) end while G.alive @@ -58,7 +59,7 @@ module Rainbows # 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[0].each do |s| - s = Rainbows.accept(s) and process_client(s) + s = accept(s) and process_client(s) end rescue Errno::EINTR rescue => e diff --git a/lib/rainbows/thread_spawn.rb b/lib/rainbows/thread_spawn.rb index 6952f26..0d4973a 100644 --- a/lib/rainbows/thread_spawn.rb +++ b/lib/rainbows/thread_spawn.rb @@ -18,6 +18,7 @@ module Rainbows module ThreadSpawn include Base + include Rainbows::Acceptor def accept_loop(klass) #:nodoc: lock = Mutex.new @@ -36,7 +37,7 @@ module Rainbows # CPU during I/O wait, CPU cycles that can be better used # by other worker _processes_. sleep(0.01) - elsif c = Rainbows.sync_accept(l) + elsif c = sync_accept(l) klass.new(c) do |c| begin lock.synchronize { G.cur += 1 } |