-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(signals): loop sigtimedwait() on SIGWINCH (#32)
Our signal-handling looks a little different than resty-cli, which uses sigaction() to register a signal handler function. rusty-cli uses sigtimedwait() because the API and control flow is much more convenient. Previously we were exiting our signal-handling phase after the first signal was caught, forwarding it to the child process and then wait4()-ing for it to exit. This is mostly correct, except in the case of SIGWINCH, which isn't a "you should probably stop now/soon" signal. To fix this we loop over sigtimedwait() until we get a non-SIGWINCH signal. I've also attempted to fix a race condition wherein we could hang if the child process exited before we could set up our signal blocking mask and await signal delivery by explicitly checking the child process on each iteration _before_ blocking for signal delivery.
- Loading branch information
Showing
4 changed files
with
99 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#!/usr/bin/env bash | ||
|
||
set -euo pipefail | ||
|
||
readonly RUSTY=./target/debug/rusty-cli | ||
readonly RESTY=./resty-cli/bin/resty | ||
|
||
test_it() { | ||
local -r bin=$1 | ||
echo "TEST: $bin" | ||
|
||
local tmp; tmp=$(mktemp) | ||
|
||
"$bin" \ | ||
-e "local fh = io.open('$tmp', 'w+'); fh:write(ngx.config.prefix()); fh:flush(); fh:close()" \ | ||
-e 'ngx.sleep(60)' \ | ||
& | ||
|
||
local pid=$! | ||
|
||
while [[ ! -s "$tmp" ]]; do | ||
kill -0 "$pid" || { | ||
echo "fatal: $pid died while we were waiting" | ||
exit 1 | ||
} | ||
sleep 1 | ||
done | ||
|
||
local prefix; prefix=$(<"$tmp") | ||
if [[ -d $prefix ]]; then | ||
echo "prefix dir: $prefix" | ||
else | ||
echo "fatal: nginx prefix dir ($prefix) does not exist at startup" | ||
exit 1 | ||
fi | ||
|
||
echo -n "sending WINCH..." | ||
for _ in {1..20}; do | ||
echo -n . | ||
kill -WINCH "$pid" | ||
sleep 0.1 | ||
done | ||
|
||
echo | ||
|
||
if [[ ! -d $prefix ]]; then | ||
echo "fatal: nginx prefix dir ($prefix) does not exist after WINCH" | ||
fi | ||
|
||
echo "sending INT..." | ||
kill -INT "$pid" | ||
|
||
set +e | ||
wait "$pid" | ||
ec=$? | ||
set -e | ||
|
||
echo "$bin has exited with code: $ec" | ||
|
||
if [[ -d $prefix ]]; then | ||
echo "FAILED: nginx prefix dir ($prefix) still exists after stopping" | ||
exit 1 | ||
fi | ||
|
||
if (( ec != 130 )); then | ||
echo "FAILED: unexpected exit code ($ec)" | ||
exit 1 | ||
fi | ||
|
||
echo "OK" | ||
} | ||
|
||
test_it "$RESTY" | ||
test_it "$RUSTY" |