about summary refs log tree commit homepage
diff options
authorEric Wong <e@yhbt.net>2020-04-16 09:24:57 +0000
committerEric Wong <bofh@yhbt.net>2020-04-16 09:25:31 +0000
commit221340c4ebc1566677a29551bf4be7c05fc64b07 (patch)
parent00346227dfe91a6a11f95a679cef38940f79f12a (diff)
In setups with multiple listeners, it's possible for our greedy
select(2)-avoidance optimization to get pinned on a single, busy
listener and starve the other listener(s).

Prevent starvation by retrying the select(2)-avoidance
optimization if and only if all listeners were active.  This
should have no effect on the majority of deployments with only a
single listener.

Thanks to Stan Hu for reporting and testing.

Reported-by: Stan Hu <stanhu@gmail.com>
Tested-by: Stan Hu <stanhu@gmail.com>
Link: https://yhbt.net/unicorn-public/CAMBWrQ=Yh42MPtzJCEO7XryVknDNetRMuA87irWfqVuLdJmiBQ@mail.gmail.com/
1 files changed, 2 insertions, 1 deletions
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index a52931a..45a2e97 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -686,6 +686,7 @@ class Unicorn::HttpServer
     trap(:USR1) { nr = -65536 }
     ready = readers.dup
+    nr_listeners = readers.size
     @after_worker_ready.call(self, worker)
@@ -708,7 +709,7 @@ class Unicorn::HttpServer
       # we're probably reasonably busy, so avoid calling select()
       # and do a speculative non-blocking accept() on ready listeners
       # before we sleep again in select().
-      unless nr == 0
+      if nr == nr_listeners
         tmp = ready.dup