about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/unicorn.rb18
-rw-r--r--lib/unicorn/http_request.rb1
-rw-r--r--lib/unicorn/launcher.rb2
-rw-r--r--test/unit/test_util.rb25
4 files changed, 42 insertions, 4 deletions
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index 85e4df1..b6dae36 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -2,6 +2,7 @@
 require 'etc'
 require 'stringio'
 require 'kgio'
+require 'raindrops'
 require 'io/wait'
 
 begin
@@ -113,9 +114,22 @@ module Unicorn
     exc.backtrace.each { |line| logger.error(line) }
   end
 
-  # remove this when we only support Ruby >= 2.0
+  F_SETPIPE_SZ = 1031 if RUBY_PLATFORM =~ /linux/
+
   def self.pipe # :nodoc:
-    Kgio::Pipe.new.each { |io| io.close_on_exec = true }
+    Kgio::Pipe.new.each do |io|
+      io.close_on_exec = true  # remove this when we only support Ruby >= 2.0
+
+      # shrink pipes to minimize impact on /proc/sys/fs/pipe-user-pages-soft
+      # limits.
+      if defined?(F_SETPIPE_SZ)
+        begin
+          io.fcntl(F_SETPIPE_SZ, Raindrops::PAGE_SIZE)
+        rescue Errno::EINVAL
+          # old kernel
+        end
+      end
+    end
   end
   # :startdoc:
 end
diff --git a/lib/unicorn/http_request.rb b/lib/unicorn/http_request.rb
index d713b19..8bb884b 100644
--- a/lib/unicorn/http_request.rb
+++ b/lib/unicorn/http_request.rb
@@ -2,7 +2,6 @@
 # :enddoc:
 # no stable API here
 require 'unicorn_http'
-require 'raindrops'
 
 # TODO: remove redundant names
 Unicorn.const_set(:HttpRequest, Unicorn::HttpParser)
diff --git a/lib/unicorn/launcher.rb b/lib/unicorn/launcher.rb
index 5eafe5b..78e8f39 100644
--- a/lib/unicorn/launcher.rb
+++ b/lib/unicorn/launcher.rb
@@ -31,7 +31,7 @@ module Unicorn::Launcher
       #  \_ parent  - exits immediately ASAP
       #      \_ unicorn master - writes to pipe when ready
 
-      rd, wr = IO.pipe
+      rd, wr = Unicorn.pipe
       grandparent = $$
       if fork
         wr.close # grandparent does not write
diff --git a/test/unit/test_util.rb b/test/unit/test_util.rb
index dc6302e..9d5d4ef 100644
--- a/test/unit/test_util.rb
+++ b/test/unit/test_util.rb
@@ -102,4 +102,29 @@ class TestUtil < Test::Unit::TestCase
     }
     tmp.close!
   end
+
+  def test_pipe
+    r, w = Unicorn.pipe
+    assert r
+    assert w
+
+    return if RUBY_PLATFORM !~ /linux/
+
+    begin
+      f_getpipe_sz = 1032
+      IO.pipe do |a, b|
+        a_sz = a.fcntl(f_getpipe_sz)
+        b_sz = b.fcntl(f_getpipe_sz)
+        assert_kind_of Integer, a_sz
+        r_sz = r.fcntl(f_getpipe_sz)
+        assert_equal Raindrops::PAGE_SIZE, r_sz
+        assert_operator a_sz, :>=, r_sz
+      end
+    rescue Errno::EINVAL
+      # Linux <= 2.6.34
+    end
+  ensure
+    w.close
+    r.close
+  end
 end