From 253f44cb908fd20a4de661d4d90e62665b2ed1dc Mon Sep 17 00:00:00 2001 From: Tudor Bosman Date: Sat, 21 Sep 2013 19:03:20 -0700 Subject: [PATCH] Fix small race in subprocess_test Summary: It is possible for subprocess_test_parent_death_helper's child to signal the parent between the check for "caught" and the call to "pause()", and therefore pause() blocks forever. Test Plan: ran the test in a loop Reviewed By: delong.j@fb.com FB internal diff: D979872 --- .../test/SubprocessTestParentDeathHelper.cpp | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/folly/test/SubprocessTestParentDeathHelper.cpp b/folly/test/SubprocessTestParentDeathHelper.cpp index 2eae7a3c..66277452 100644 --- a/folly/test/SubprocessTestParentDeathHelper.cpp +++ b/folly/test/SubprocessTestParentDeathHelper.cpp @@ -40,30 +40,21 @@ DEFINE_bool(child, false, ""); namespace { constexpr int kSignal = SIGUSR1; -volatile bool caught = false; - -void signalHandler(int sig) { - if (sig != kSignal) { - abort(); - } - caught = true; -} - } // namespace void runChild(const char* file) { - struct sigaction sa; - sa.sa_handler = signalHandler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - CHECK_ERR(sigaction(kSignal, &sa, nullptr)); + // Block SIGUSR1 so it's queued + sigset_t sigs; + CHECK_ERR(sigemptyset(&sigs)); + CHECK_ERR(sigaddset(&sigs, kSignal)); + CHECK_ERR(sigprocmask(SIG_BLOCK, &sigs, nullptr)); // Kill the parent, wait for our signal. CHECK_ERR(kill(getppid(), SIGKILL)); - while (!caught) { - pause(); - } + int sig = 0; + CHECK_ERR(sigwait(&sigs, &sig)); + CHECK_EQ(sig, kSignal); // Signal completion by creating the file CHECK_ERR(creat(file, 0600)); -- 2.34.1