From: Tudor Bosman Date: Sun, 22 Sep 2013 02:03:20 +0000 (-0700) Subject: Fix small race in subprocess_test X-Git-Tag: v0.22.0~870 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=253f44cb908fd20a4de661d4d90e62665b2ed1dc;p=folly.git 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 --- 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));