Fix small race in subprocess_test
authorTudor Bosman <tudorb@fb.com>
Sun, 22 Sep 2013 02:03:20 +0000 (19:03 -0700)
committerJordan DeLong <jdelong@fb.com>
Sun, 22 Sep 2013 23:40:33 +0000 (16:40 -0700)
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

folly/test/SubprocessTestParentDeathHelper.cpp

index 2eae7a3ce9208ddf130a3af27db4825bff859f7f..662774520bdc047f004c93bfbf4a30895ee0eec9 100644 (file)
@@ -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));