about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-12-27 19:38:39 -0800
committerEric Wong <normalperson@yhbt.net>2009-12-27 19:38:39 -0800
commit36888441021fbb0ae0cf724dc4e700d316b4d1bd (patch)
tree982d3ff0d80d361a1204bd88d57dabf9e21fcf21 /lib
parent5eea32764571b721cd1a89cf9ebfa853c621ac9e (diff)
downloadunicorn-36888441021fbb0ae0cf724dc4e700d316b4d1bd.tar.gz
Otherwise the original spawner process may not notice the close
as it's still being shared by workers.  While we're at it, avoid
confusing the original spawner by using readpartial instead of
sysread.
Diffstat (limited to 'lib')
-rw-r--r--lib/unicorn.rb17
-rw-r--r--lib/unicorn/launcher.rb2
2 files changed, 12 insertions, 7 deletions
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index ae05f03..114ef9d 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -25,8 +25,7 @@ module Unicorn
 
   class << self
     def run(app, options = {})
-      ready_pipe = options.delete(:ready_pipe)
-      HttpServer.new(app, options).start.join(ready_pipe)
+      HttpServer.new(app, options).start.join
     end
   end
 
@@ -39,7 +38,7 @@ module Unicorn
                                 :before_fork, :after_fork, :before_exec,
                                 :logger, :pid, :app, :preload_app,
                                 :reexec_pid, :orig_app, :init_listeners,
-                                :master_pid, :config)
+                                :master_pid, :config, :ready_pipe)
     include ::Unicorn::SocketHelper
 
     # prevents IO objects in here from being GC-ed
@@ -163,6 +162,7 @@ module Unicorn
     def initialize(app, options = {})
       self.app = app
       self.reexec_pid = 0
+      self.ready_pipe = options.delete(:ready_pipe)
       self.init_listeners = options[:listeners] ? options[:listeners].dup : []
       self.config = Configurator.new(options.merge(:use_defaults => true))
       self.listener_opts = {}
@@ -314,7 +314,7 @@ module Unicorn
     # (or until a termination signal is sent).  This handles signals
     # one-at-a-time time and we'll happily drop signals in case somebody
     # is signalling us too often.
-    def join(ready_pipe = nil)
+    def join
       # this pipe is used to wake us up from select(2) in #join when signals
       # are trapped.  See trap_deferred
       init_self_pipe!
@@ -327,7 +327,8 @@ module Unicorn
       logger.info "master process ready" # test_exec.rb relies on this message
       if ready_pipe
         ready_pipe.syswrite($$.to_s)
-        ready_pipe.close
+        ready_pipe.close rescue nil
+        self.ready_pipe = nil
       end
       begin
         loop do
@@ -533,7 +534,11 @@ module Unicorn
         WORKERS.values.include?(worker_nr) and next
         worker = Worker.new(worker_nr, Unicorn::Util.tmpio)
         before_fork.call(self, worker)
-        WORKERS[fork { worker_loop(worker) }] = worker
+        WORKERS[fork {
+          ready_pipe.close if ready_pipe
+          self.ready_pipe = nil
+          worker_loop(worker)
+        }] = worker
       end
     end
 
diff --git a/lib/unicorn/launcher.rb b/lib/unicorn/launcher.rb
index 2d6ad97..0ea836b 100644
--- a/lib/unicorn/launcher.rb
+++ b/lib/unicorn/launcher.rb
@@ -42,7 +42,7 @@ class Unicorn::Launcher
 
       if grandparent == $$
         # this will block until HttpServer#join runs (or it dies)
-        master_pid = rd.sysread(16).to_i
+        master_pid = rd.readpartial(16).to_i
         exit!(1) unless master_pid > 1
         exit 0
       else # unicorn master process