use default SIGCHLD handler
authorEric Wong <normalperson@yhbt.net>
Sat, 3 Dec 2011 01:38:48 +0000 (2 17:38 -0800)
committerEric Wong <normalperson@yhbt.net>
Sat, 3 Dec 2011 01:42:02 +0000 (2 17:42 -0800)
Applications that fork() will trigger SIGCHLD.  As unicorn is
based on the master+worker model, its master process handles
SIGCHLD when workers die.  However, Zbatery is single-process
and has no workers, it does not need a custom SIGCHLD handler.

lib/zbatery.rb
t/sigchld.ru [new file with mode: 0644]
t/t0006-sigchld.sh [new file with mode: 0755]

index 735b1e6..5d208b1 100644 (file)
@@ -82,6 +82,7 @@ module Rainbows
       trap(:USR1) { Thread.new { reopen_logs } }
       trap(:USR2) { Thread.new { reexec } }
       trap(:HUP) { Thread.new { reexec; stop } }
+      trap(:CHLD, "DEFAULT")
 
       # technically feasible in some cases, just not sanely supportable:
       %w(TTIN TTOU WINCH).each do |sig|
diff --git a/t/sigchld.ru b/t/sigchld.ru
new file mode 100644 (file)
index 0000000..4f3b566
--- /dev/null
@@ -0,0 +1,22 @@
+#\ -E none
+use Rack::ContentLength
+use Rack::ContentType, "text/plain"
+run lambda { |env|
+  rv = case env["PATH_INFO"]
+  when "/backtick"
+    `printf 'hi'`
+  when "/system"
+    rv = system("true")
+    rv.to_s
+  when "/fork_ignore"
+    pid = fork {}
+    pid.class.to_s
+  when "/fork_wait"
+    _, status = Process.waitpid2(fork {})
+    status.success?.to_s
+  when "/popen"
+    io = IO.popen('echo popen')
+    io.read
+  end
+  [ 200, {}, [ rv ] ]
+}
diff --git a/t/t0006-sigchld.sh b/t/t0006-sigchld.sh
new file mode 100755 (executable)
index 0000000..35076f3
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/sh
+. ./test-lib.sh
+
+# FIXME: fork + Fibers segfaults: https://redmine.ruby-lang.org/issues/5700
+skip_models NeverBlock FiberSpawn FiberPool CoolioFiberSpawn
+
+t_plan 8 "SIGCHLD handling for $model"
+
+t_begin "setup and startup" && {
+       rtmpfiles curl_out
+       zbatery_setup $model
+       zbatery -D sigchld.ru -c $unicorn_config
+       zbatery_wait_start
+}
+
+t_begin "backtick" && {
+       test xhi = x"$(curl -sSf http://$listen/backtick)"
+}
+
+t_begin "system" && {
+       test xtrue = x"$(curl -sSf http://$listen/system)"
+}
+
+t_begin "fork_ignore" && {
+       test xFixnum = x"$(curl -sSf http://$listen/fork_ignore)"
+}
+
+t_begin "fork_wait" && {
+       test xtrue = x"$(curl -sSf http://$listen/fork_wait)"
+}
+
+t_begin "popen" && {
+       test xpopen = x"$(curl -sSf http://$listen/popen)"
+}
+
+t_begin "shutdown server" && {
+       kill -QUIT $zbatery_pid
+}
+
+dbgcat r_err
+
+t_begin "check stderr" && check_stderr
+
+t_done