From 1bdb4eda0d868223bd6b3d92db4545a02f5e14f9 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 26 Feb 2013 21:02:34 +0000 Subject: [PATCH] epoll/*: remove user-space array as active queue This prevents pathological starvation cases where the user-space ready-list can be repopulated infinitely. With EPOLLONESHOT, epoll itself may be used for this task (at a slightly higher cost) by enabling read/write checks, as the epoll ready-list preserves event ordering when used with EPOLLONESHOT. --- lib/rainbows/epoll/client.rb | 11 ++++------- lib/rainbows/xepoll/client.rb | 3 --- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/rainbows/epoll/client.rb b/lib/rainbows/epoll/client.rb index f6af6fa..65fcb3e 100644 --- a/lib/rainbows/epoll/client.rb +++ b/lib/rainbows/epoll/client.rb @@ -6,14 +6,14 @@ module Rainbows::Epoll::Client include Rainbows::EvCore APP = Rainbows.server.app Server = Rainbows::Epoll::Server - IN = SleepyPenguin::Epoll::IN | SleepyPenguin::Epoll::ET - OUT = SleepyPenguin::Epoll::OUT | SleepyPenguin::Epoll::ET + IN = SleepyPenguin::Epoll::IN | SleepyPenguin::Epoll::ONESHOT + OUT = SleepyPenguin::Epoll::OUT | SleepyPenguin::Epoll::ONESHOT + EPINOUT = IN | OUT KATO = {} KATO.compare_by_identity if KATO.respond_to?(:compare_by_identity) Rainbows.at_quit { KATO.each_key { |k| k.timeout! }.clear } Rainbows.config!(self, :keepalive_timeout) EP = Rainbows::EP - ReRun = [] @@last_expire = Time.now def self.expire @@ -28,9 +28,6 @@ module Rainbows::Epoll::Client def self.loop begin EP.wait(nil, 1000) { |_, obj| obj.epoll_run } - while obj = ReRun.shift - obj.epoll_run - end expire rescue Errno::EINTR rescue => e @@ -140,7 +137,7 @@ module Rainbows::Epoll::Client end def want_more - ReRun << self + EP.set(self, EPINOUT) end def on_deferred_write_complete diff --git a/lib/rainbows/xepoll/client.rb b/lib/rainbows/xepoll/client.rb index 4f15a73..f518db5 100644 --- a/lib/rainbows/xepoll/client.rb +++ b/lib/rainbows/xepoll/client.rb @@ -27,9 +27,6 @@ module Rainbows::XEpoll::Client def self.loop begin EP.wait(nil, 1000) { |_, obj| obj.epoll_run } - while obj = ReRun.shift - obj.epoll_run - end Rainbows::Epoll::Client.expire rescue Errno::EINTR rescue => e -- 2.11.4.GIT