diff options
Diffstat (limited to 'lib/rainbows')
-rw-r--r-- | lib/rainbows/thread_spawn.rb | 12 | ||||
-rw-r--r-- | lib/rainbows/worker_yield.rb | 15 | ||||
-rw-r--r-- | lib/rainbows/writer_thread_spawn/client.rb | 5 |
3 files changed, 19 insertions, 13 deletions
diff --git a/lib/rainbows/thread_spawn.rb b/lib/rainbows/thread_spawn.rb index a0ccde6..9da75f1 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::WorkerYield def accept_loop(klass) #:nodoc: lock = Mutex.new @@ -26,16 +27,7 @@ module Rainbows klass.new(l) do |l| begin if lock.synchronize { G.cur >= limit } - # 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. - # We don't use Thread.pass because it needlessly spins the - # CPU during I/O wait, CPU cycles that can be better used - # by other worker _processes_. - sleep(0.01) + worker_yield elsif c = l.kgio_accept klass.new(c) do |c| begin diff --git a/lib/rainbows/worker_yield.rb b/lib/rainbows/worker_yield.rb new file mode 100644 index 0000000..ec2a289 --- /dev/null +++ b/lib/rainbows/worker_yield.rb @@ -0,0 +1,15 @@ +# :enddoc: +module Rainbows::WorkerYield + + # Sleep if we're busy (and let other threads run). 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. We don't use Thread.pass because it needlessly + # spins the CPU during I/O wait, CPU cycles that can be better used by + # other worker _processes_. + def worker_yield + sleep(0.01) + end +end diff --git a/lib/rainbows/writer_thread_spawn/client.rb b/lib/rainbows/writer_thread_spawn/client.rb index f9c373e..ed60f42 100644 --- a/lib/rainbows/writer_thread_spawn/client.rb +++ b/lib/rainbows/writer_thread_spawn/client.rb @@ -4,6 +4,7 @@ class Rainbows::WriterThreadSpawn::Client < Struct.new(:to_io, :q, :thr) include Rainbows::Response include Rainbows::SocketProxy + include Rainbows::WorkerYield CUR = {} # :nodoc: @@ -17,12 +18,10 @@ class Rainbows::WriterThreadSpawn::Client < Struct.new(:to_io, :q, :thr) end def queue_writer - # not using Thread.pass here because that spins the CPU during - # I/O wait and will eat cycles from other worker processes. until CUR.size < MAX CUR.delete_if { |t,_| t.alive? ? t.join(0) : true - }.size >= MAX and sleep(0.01) + }.size >= MAX and worker_yield end q = Queue.new |