diff options
author | Eric Wong <normalperson@yhbt.net> | 2010-06-18 08:10:55 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2010-06-18 08:10:55 +0000 |
commit | b290a65eb735aa89bb071e27f8421cc864c78e8c (patch) | |
tree | 52219aa1a4e34d351c0e833819ad26ad1f8667dd /lib/rainbows/fiber | |
parent | b5a24fdbf928b675e478987393212651ef5909d6 (diff) | |
download | rainbows-b290a65eb735aa89bb071e27f8421cc864c78e8c.tar.gz |
This gives a tiny performance improvement to the FiberSpawn and FiberPool concurrency models.
Diffstat (limited to 'lib/rainbows/fiber')
-rw-r--r-- | lib/rainbows/fiber/base.rb | 15 | ||||
-rw-r--r-- | lib/rainbows/fiber/io.rb | 14 |
2 files changed, 16 insertions, 13 deletions
diff --git a/lib/rainbows/fiber/base.rb b/lib/rainbows/fiber/base.rb index ee9e68e..93e96ca 100644 --- a/lib/rainbows/fiber/base.rb +++ b/lib/rainbows/fiber/base.rb @@ -4,11 +4,11 @@ require 'rainbows/fiber/io' module Rainbows module Fiber - # blocked readers (key: Rainbows::Fiber::IO object, value is irrelevant) - RD = {}.compare_by_identity + # blocked readers (key: fileno, value: Rainbows::Fiber::IO object) + RD = [] - # blocked writers (key: Rainbows::Fiber::IO object, value is irrelevant) - WR = {}.compare_by_identity + # blocked writers (key: fileno, value: Rainbows::Fiber::IO object) + WR = [] # sleeping fibers go here (key: Fiber object, value: wakeup time) ZZ = {}.compare_by_identity @@ -35,9 +35,10 @@ module Rainbows def schedule(&block) ret = begin G.tick - RD.keys.each { |c| c.f.resume } # attempt to time out idle clients + RD.compact.each { |c| c.f.resume } # attempt to time out idle clients t = schedule_sleepers - Kernel.select(RD.keys.concat(LISTENERS), WR.keys, nil, t) or return + Kernel.select(RD.compact.concat(LISTENERS), + WR.compact, nil, t) or return rescue Errno::EINTR retry rescue Errno::EBADF, TypeError @@ -46,7 +47,7 @@ module Rainbows end or return # active writers first, then _all_ readers for keepalive timeout - ret[1].concat(RD.keys).each { |c| c.f.resume } + ret[1].concat(RD.compact).each { |c| c.f.resume } # accept is an expensive syscall, filter out listeners we don't want (ret[0] & LISTENERS).each(&block) diff --git a/lib/rainbows/fiber/io.rb b/lib/rainbows/fiber/io.rb index 5153070..5f925ca 100644 --- a/lib/rainbows/fiber/io.rb +++ b/lib/rainbows/fiber/io.rb @@ -19,21 +19,23 @@ module Rainbows end def close - RD.delete(self) - WR.delete(self) + fileno = to_io.fileno + RD[fileno] = WR[fileno] = nil to_io.close unless to_io.closed? end def wait_readable - RD[self] = false + fileno = to_io.fileno + RD[fileno] = self ::Fiber.yield - RD.delete(self) + RD[fileno] = nil end def wait_writable - WR[self] = false + fileno = to_io.fileno + WR[fileno] = self ::Fiber.yield - WR.delete(self) + WR[fileno] = nil end def write(buf) |