From cb6d8c71abac83d75d2bc990bdbc84748a1309ea Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 19 Jan 2010 18:09:30 -0800 Subject: initialize signal handlers before writing pid file This prevents trigger-happy init scripts from reading the pid file (and thus sending signals) to a not-fully initialized master process to handle them. This does NOT fix anything if other processes are sending signals prematurely without relying on the presence of the pid file. It's not possible to prevent all cases of this in one process, even in a purely C application, so we won't bother trying. We continue to always defer signal handling to the main loop anyways, and signals sent to the master process will be deferred/ignored until Unicorn::HttpServer#join is run. --- lib/unicorn.rb | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/unicorn.rb b/lib/unicorn.rb index 7a1ef34..e3e4315 100644 --- a/lib/unicorn.rb +++ b/lib/unicorn.rb @@ -210,7 +210,18 @@ module Unicorn end config_listeners.each { |addr| listen(addr) } raise ArgumentError, "no listeners" if LISTENERS.empty? + + # this pipe is used to wake us up from select(2) in #join when signals + # are trapped. See trap_deferred. + init_self_pipe! + + # setup signal handlers before writing pid file in case people get + # trigger happy and send signals as soon as the pid file exists. + # Note that signals don't actually get handled until the #join method + QUEUE_SIGS.each { |sig| trap_deferred(sig) } + trap(:CHLD) { |_| awaken_master } self.pid = config[:pid] + self.master_pid = $$ build_app! if preload_app maintain_worker_count @@ -322,14 +333,9 @@ module Unicorn # one-at-a-time time and we'll happily drop signals in case somebody # is signalling us too often. 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! respawn = true last_check = Time.now - QUEUE_SIGS.each { |sig| trap_deferred(sig) } - trap(:CHLD) { |sig_nr| awaken_master } proc_name 'master' logger.info "master process ready" # test_exec.rb relies on this message if ready_pipe -- cgit v1.2.3-24-ge0c7