Wait for all threads to finish executing before leaving in an EventBase test
authorChristopher Dykes <cdykes@fb.com>
Wed, 10 Aug 2016 00:33:05 +0000 (17:33 -0700)
committerFacebook Github Bot 0 <facebook-github-bot-0-bot@fb.com>
Wed, 10 Aug 2016 00:38:28 +0000 (17:38 -0700)
Summary:
If one of the assertions failed, it would result in any threads that are still running accessing already-disposed data, so wait for the threads to exit, even when an exception is thrown.

This also slightly cleans up the handling of threads a bit further down, because the mess it was doing was completely unnecessary.

Reviewed By: yfeldblum

Differential Revision: D3692438

fbshipit-source-id: 9082ba248b2cf1062e46c97faf0bc062312ee9ae

folly/io/async/test/EventBaseTest.cpp

index 29cf89fdd06e2175f3fb085bab57f60d87c32a81..11f61187fa74cd8919798c8a4ea8a7e746fe1b02 100644 (file)
@@ -1121,6 +1121,13 @@ TEST(EventBaseTest, RunInThread) {
   RunInThreadData data(numThreads, opsPerThread);
 
   deque<std::thread> threads;
+  SCOPE_EXIT {
+    // Wait on all of the threads.
+    for (auto& thread : threads) {
+      thread.join();
+    }
+  };
+
   for (uint32_t i = 0; i < numThreads; ++i) {
     threads.emplace_back([i, &data] {
         for (int n = 0; n < data.opsPerThread; ++n) {
@@ -1186,24 +1193,23 @@ TEST(EventBaseTest, RunInEventBaseThreadAndWait) {
     auto& atom = atoms.at(i);
     atom = make_unique<atomic<size_t>>(0);
   }
-  vector<thread> threads(c);
+  vector<thread> threads;
   for (size_t i = 0; i < c; ++i) {
-    auto& atom = *atoms.at(i);
-    auto& th = threads.at(i);
-    th = thread([&atom] {
-        EventBase eb;
-        auto ebth = thread([&]{ eb.loopForever(); });
-        eb.waitUntilRunning();
-        eb.runInEventBaseThreadAndWait([&] {
-          size_t x = 0;
-          atom.compare_exchange_weak(
-              x, 1, std::memory_order_release, std::memory_order_relaxed);
-        });
+    threads.emplace_back([&atoms, i] {
+      EventBase eb;
+      auto& atom = *atoms.at(i);
+      auto ebth = thread([&] { eb.loopForever(); });
+      eb.waitUntilRunning();
+      eb.runInEventBaseThreadAndWait([&] {
         size_t x = 0;
         atom.compare_exchange_weak(
-            x, 2, std::memory_order_release, std::memory_order_relaxed);
-        eb.terminateLoopSoon();
-        ebth.join();
+            x, 1, std::memory_order_release, std::memory_order_relaxed);
+      });
+      size_t x = 0;
+      atom.compare_exchange_weak(
+          x, 2, std::memory_order_release, std::memory_order_relaxed);
+      eb.terminateLoopSoon();
+      ebth.join();
     });
   }
   for (size_t i = 0; i < c; ++i) {