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. --- test/test_helper.rb | 5 +++++ test/unit/test_server.rb | 1 + test/unit/test_signals.rb | 6 +++++- test/unit/test_upload.rb | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/test_helper.rb b/test/test_helper.rb index 3bdbeb1..5b750ee 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -294,3 +294,8 @@ def chunked_spawn(stdout, *cmd) end while true } end + +def reset_sig_handlers + sigs = %w(CHLD).concat(Unicorn::HttpServer::QUEUE_SIGS) + sigs.each { |sig| trap(sig, "DEFAULT") } +end diff --git a/test/unit/test_server.rb b/test/unit/test_server.rb index 00705d0..36333a0 100644 --- a/test/unit/test_server.rb +++ b/test/unit/test_server.rb @@ -41,6 +41,7 @@ class WebServerTest < Test::Unit::TestCase File.truncate("test_stderr.#$$.log", 0) @server.stop(true) end + reset_sig_handlers end def test_preload_app_config diff --git a/test/unit/test_signals.rb b/test/unit/test_signals.rb index eb2af0b..71cf8f4 100644 --- a/test/unit/test_signals.rb +++ b/test/unit/test_signals.rb @@ -40,6 +40,10 @@ class SignalsTest < Test::Unit::TestCase @server = nil end + def teardown + reset_sig_handlers + end + def test_worker_dies_on_dead_master pid = fork { app = lambda { |env| [ 200, {'X-Pid' => "#$$" }, [] ] } @@ -190,7 +194,7 @@ class SignalsTest < Test::Unit::TestCase killer = fork { loop { Process.kill(:HUP, pid); sleep(0.0001) } } buf = ' ' * @bs @count.times { sock.syswrite(buf) } - Process.kill(:TERM, killer) + Process.kill(:KILL, killer) Process.waitpid2(killer) redirect_test_io { @server.stop(true) } # can't check for == since pending signals get merged diff --git a/test/unit/test_upload.rb b/test/unit/test_upload.rb index 7ac3c9e..dc0eb40 100644 --- a/test/unit/test_upload.rb +++ b/test/unit/test_upload.rb @@ -55,6 +55,7 @@ class UploadTest < Test::Unit::TestCase def teardown redirect_test_io { @server.stop(true) } if @server @random.close + reset_sig_handlers end def test_put -- cgit v1.2.3-24-ge0c7