diff --git a/hphp/test/run b/hphp/test/run index a0dc31217..dc53f05da 100755 --- a/hphp/test/run +++ b/hphp/test/run @@ -389,7 +389,7 @@ function run($options, $tests, $bad_test_file) { function run_test($options, $test) { $hhvm = hhvm_cmd($options, $test); - $hhvm = __DIR__."/../tools/timeout.sh 60 $hhvm"; + $hhvm = __DIR__."/../tools/timeout.sh -t 60 $hhvm"; $output = ""; if (isset($options['repo'])) { if (strpos($test, '.hhas') !== false || diff --git a/hphp/tools/timeout.sh b/hphp/tools/timeout.sh index 4f37d717d..5c19d2ec9 100755 --- a/hphp/tools/timeout.sh +++ b/hphp/tools/timeout.sh @@ -1,23 +1,91 @@ #!/bin/bash +# +# The Bash shell script executes a command with a time-out. +# Upon time-out expiration SIGTERM (15) is sent to the process. If the signal +# is blocked, then the subsequent SIGKILL (9) terminates it. +# +# Based on the Bash documentation example. -timeout=$1 -shift +# Hello Chet, +# please find attached a "little easier" :-) to comprehend +# time-out example. If you find it suitable, feel free to include +# anywhere: the very same logic as in the original examples/scripts, a +# little more transparent implementation to my taste. +# +# Dmitry V Golovashkin -# Start the script that does the real work. -"$@" & -pid=$! +scriptName="${0##*/}" -# Don't let the whole process take longer than 15 seconds, in case -# Phabricator is acting up. +declare -i DEFAULT_TIMEOUT=9 +declare -i DEFAULT_INTERVAL=1 +declare -i DEFAULT_DELAY=1 + +# Timeout. +declare -i timeout=DEFAULT_TIMEOUT +# Interval between checks if the process is still alive. +declare -i interval=DEFAULT_INTERVAL +# Delay between posting the SIGTERM signal and destroying the process by SIGKILL. +declare -i delay=DEFAULT_DELAY + +function printUsage() { + cat < /dev/stderr - kill $$ -) & -timeout_pid=$! + ((t = timeout)) -wait $pid 2>/dev/null -status=$? -kill $timeout_pid 2>/dev/null + while ((t > 0)); do + sleep $interval + kill -0 $$ || exit 0 + ((t -= interval)) + done -exit $status + # Be nice, post SIGTERM first. + # The 'exit 0' below will be executed if any preceeding command fails. + kill -s SIGTERM $$ && kill -0 $$ || exit 0 + sleep $delay + kill -s SIGKILL $$ +) 2> /dev/null & + +exec "$@"