about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-02-26 21:02:34 +0000
committerEric Wong <normalperson@yhbt.net>2013-02-26 21:05:55 +0000
commit1bdb4eda0d868223bd6b3d92db4545a02f5e14f9 (patch)
tree77b8442bada556449358a6ef5aec678ff5ab4d55
parent552c4ca305092911ca7613de4b1ba310e5481775 (diff)
downloadrainbows-1bdb4eda0d868223bd6b3d92db4545a02f5e14f9.tar.gz
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.
-rw-r--r--lib/rainbows/epoll/client.rb11
-rw-r--r--lib/rainbows/xepoll/client.rb3
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