Hi mclow.lists, danalbert, jroelofs,

There is a race condition in ASAN where it can perform the leak detection 
before all detached threads exit and free their resources. This can lead to 
failures in the future tests. 
This patch fixes the race condition my manually joining all threads that are 
used. This patch should not affect the functionality of the tests.

http://reviews.llvm.org/D6347

Files:
  test/thread/futures/futures.shared_future/get.pass.cpp
  test/thread/futures/futures.shared_future/wait.pass.cpp
  test/thread/futures/futures.shared_future/wait_for.pass.cpp
  test/thread/futures/futures.shared_future/wait_until.pass.cpp
  test/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
  
test/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
  test/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
  test/thread/futures/futures.unique_future/get.pass.cpp
  test/thread/futures/futures.unique_future/wait.pass.cpp
  test/thread/futures/futures.unique_future/wait_for.pass.cpp
  test/thread/futures/futures.unique_future/wait_until.pass.cpp
Index: test/thread/futures/futures.shared_future/get.pass.cpp
===================================================================
--- test/thread/futures/futures.shared_future/get.pass.cpp
+++ test/thread/futures/futures.shared_future/get.pass.cpp
@@ -66,15 +66,16 @@
         {
             std::promise<T> p;
             std::shared_future<T> f = p.get_future();
-            std::thread(func1, std::move(p)).detach();
+            std::thread t(func1, std::move(p));
             assert(f.valid());
             assert(f.get() == 3);
             assert(f.valid());
+            t.join();
         }
         {
             std::promise<T> p;
             std::shared_future<T> f = p.get_future();
-            std::thread(func2, std::move(p)).detach();
+            std::thread t(func2, std::move(p));
             try
             {
                 assert(f.valid());
@@ -86,22 +87,24 @@
                 assert(i == 3);
             }
             assert(f.valid());
+            t.join();
         }
     }
     {
         typedef int& T;
         {
             std::promise<T> p;
             std::shared_future<T> f = p.get_future();
-            std::thread(func3, std::move(p)).detach();
+            std::thread t(func3, std::move(p));
             assert(f.valid());
             assert(f.get() == 5);
             assert(f.valid());
+            t.join();
         }
         {
             std::promise<T> p;
             std::shared_future<T> f = p.get_future();
-            std::thread(func4, std::move(p)).detach();
+            std::thread t(func4, std::move(p));
             try
             {
                 assert(f.valid());
@@ -113,22 +116,24 @@
                 assert(i == 3.5);
             }
             assert(f.valid());
+            t.join();
         }
     }
     {
         typedef void T;
         {
             std::promise<T> p;
             std::shared_future<T> f = p.get_future();
-            std::thread(func5, std::move(p)).detach();
+            std::thread t(func5, std::move(p));
             assert(f.valid());
             f.get();
             assert(f.valid());
+            t.join();
         }
         {
             std::promise<T> p;
             std::shared_future<T> f = p.get_future();
-            std::thread(func6, std::move(p)).detach();
+            std::thread t(func6, std::move(p));
             try
             {
                 assert(f.valid());
@@ -140,6 +145,7 @@
                 assert(i == 'c');
             }
             assert(f.valid());
+            t.join();
         }
     }
 }
Index: test/thread/futures/futures.shared_future/wait.pass.cpp
===================================================================
--- test/thread/futures/futures.shared_future/wait.pass.cpp
+++ test/thread/futures/futures.shared_future/wait.pass.cpp
@@ -47,42 +47,45 @@
         typedef int T;
         std::promise<T> p;
         std::shared_future<T> f = p.get_future();
-        std::thread(func1, std::move(p)).detach();
+        std::thread t(func1, std::move(p));
         assert(f.valid());
         f.wait();
         assert(f.valid());
         Clock::time_point t0 = Clock::now();
         f.wait();
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
     {
         typedef int& T;
         std::promise<T> p;
         std::shared_future<T> f = p.get_future();
-        std::thread(func3, std::move(p)).detach();
+        std::thread t(func3, std::move(p));
         assert(f.valid());
         f.wait();
         assert(f.valid());
         Clock::time_point t0 = Clock::now();
         f.wait();
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
     {
         typedef void T;
         std::promise<T> p;
         std::shared_future<T> f = p.get_future();
-        std::thread(func5, std::move(p)).detach();
+        std::thread t(func5, std::move(p));
         assert(f.valid());
         f.wait();
         assert(f.valid());
         Clock::time_point t0 = Clock::now();
         f.wait();
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
 }
Index: test/thread/futures/futures.shared_future/wait_for.pass.cpp
===================================================================
--- test/thread/futures/futures.shared_future/wait_for.pass.cpp
+++ test/thread/futures/futures.shared_future/wait_for.pass.cpp
@@ -50,7 +50,7 @@
         typedef int T;
         std::promise<T> p;
         std::shared_future<T> f = p.get_future();
-        std::thread(func1, std::move(p)).detach();
+        std::thread t(func1, std::move(p));
         assert(f.valid());
         assert(f.wait_for(ms(300)) == std::future_status::timeout);
         assert(f.valid());
@@ -61,12 +61,13 @@
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
     {
         typedef int& T;
         std::promise<T> p;
         std::shared_future<T> f = p.get_future();
-        std::thread(func3, std::move(p)).detach();
+        std::thread t(func3, std::move(p));
         assert(f.valid());
         assert(f.wait_for(ms(300)) == std::future_status::timeout);
         assert(f.valid());
@@ -77,12 +78,13 @@
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
     {
         typedef void T;
         std::promise<T> p;
         std::shared_future<T> f = p.get_future();
-        std::thread(func5, std::move(p)).detach();
+        std::thread t(func5, std::move(p));
         assert(f.valid());
         assert(f.wait_for(ms(300)) == std::future_status::timeout);
         assert(f.valid());
@@ -93,5 +95,6 @@
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
 }
Index: test/thread/futures/futures.shared_future/wait_until.pass.cpp
===================================================================
--- test/thread/futures/futures.shared_future/wait_until.pass.cpp
+++ test/thread/futures/futures.shared_future/wait_until.pass.cpp
@@ -50,7 +50,7 @@
         typedef int T;
         std::promise<T> p;
         std::shared_future<T> f = p.get_future();
-        std::thread(func1, std::move(p)).detach();
+        std::thread t(func1, std::move(p));
         assert(f.valid());
         assert(f.wait_until(Clock::now() + ms(300)) == std::future_status::timeout);
         assert(f.valid());
@@ -61,12 +61,13 @@
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
     {
         typedef int& T;
         std::promise<T> p;
         std::shared_future<T> f = p.get_future();
-        std::thread(func3, std::move(p)).detach();
+        std::thread t(func3, std::move(p));
         assert(f.valid());
         assert(f.wait_until(Clock::now() + ms(300)) == std::future_status::timeout);
         assert(f.valid());
@@ -77,12 +78,13 @@
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
     {
         typedef void T;
         std::promise<T> p;
         std::shared_future<T> f = p.get_future();
-        std::thread(func5, std::move(p)).detach();
+        std::thread t(func5, std::move(p));
         assert(f.valid());
         assert(f.wait_until(Clock::now() + ms(300)) == std::future_status::timeout);
         assert(f.valid());
@@ -93,5 +95,6 @@
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
 }
Index: test/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
===================================================================
--- test/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
+++ test/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
@@ -42,7 +42,7 @@
     {
         std::packaged_task<double(int, char)> p(A(5));
         std::future<double> f = p.get_future();
-        std::thread(func, std::move(p)).detach();
+        std::thread t(func, std::move(p));
         try
         {
             double i = f.get();
@@ -52,11 +52,13 @@
         {
             assert(e.code() == make_error_code(std::future_errc::broken_promise));
         }
+        t.join();
     }
     {
         std::packaged_task<double(int, char)> p(A(5));
         std::future<double> f = p.get_future();
-        std::thread(func2, std::move(p)).detach();
+        std::thread t(func2, std::move(p));
         assert(f.get() == 105.0);
+        t.join();
     }
 }
Index: test/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
===================================================================
--- test/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
+++ test/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
@@ -75,13 +75,14 @@
     {
         std::packaged_task<double(int, char)> p(A(5));
         std::future<double> f = p.get_future();
-        std::thread(func0, std::move(p)).detach();
+        std::thread t(func0, std::move(p));
         assert(f.get() == 105.0);
+        t.join();
     }
     {
         std::packaged_task<double(int, char)> p(A(5));
         std::future<double> f = p.get_future();
-        std::thread(func1, std::move(p)).detach();
+        std::thread t(func1, std::move(p));
         try
         {
             f.get();
@@ -91,12 +92,14 @@
         {
             assert(e(3, 'a') == 106);
         }
+        t.join();
     }
     {
         std::packaged_task<double(int, char)> p(A(5));
         std::future<double> f = p.get_future();
-        std::thread(func2, std::move(p)).detach();
+        std::thread t(func2, std::move(p));
         assert(f.get() == 105.0);
+        t.join();
     }
     {
         std::packaged_task<double(int, char)> p;
Index: test/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
===================================================================
--- test/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
+++ test/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
@@ -75,13 +75,14 @@
     {
         std::packaged_task<double(int, char)> p(A(5));
         std::future<double> f = p.get_future();
-        std::thread(func0, std::move(p)).detach();
+        std::thread t(func0, std::move(p));
         assert(f.get() == 105.0);
+        t.join();
     }
     {
         std::packaged_task<double(int, char)> p(A(5));
         std::future<double> f = p.get_future();
-        std::thread(func1, std::move(p)).detach();
+        std::thread t(func1, std::move(p));
         try
         {
             f.get();
@@ -91,6 +92,7 @@
         {
             assert(e(3, 'a') == 106);
         }
+        t.join();
     }
     {
         std::packaged_task<double(int, char)> p(A(5));
Index: test/thread/futures/futures.unique_future/get.pass.cpp
===================================================================
--- test/thread/futures/futures.unique_future/get.pass.cpp
+++ test/thread/futures/futures.unique_future/get.pass.cpp
@@ -66,15 +66,16 @@
         {
             std::promise<T> p;
             std::future<T> f = p.get_future();
-            std::thread(func1, std::move(p)).detach();
+            std::thread t(func1, std::move(p));
             assert(f.valid());
             assert(f.get() == 3);
             assert(!f.valid());
+            t.join();
         }
         {
             std::promise<T> p;
             std::future<T> f = p.get_future();
-            std::thread(func2, std::move(p)).detach();
+            std::thread t(func2, std::move(p));
             try
             {
                 assert(f.valid());
@@ -86,22 +87,24 @@
                 assert(i == 3);
             }
             assert(!f.valid());
+            t.join();
         }
     }
     {
         typedef int& T;
         {
             std::promise<T> p;
             std::future<T> f = p.get_future();
-            std::thread(func3, std::move(p)).detach();
+            std::thread t(func3, std::move(p));
             assert(f.valid());
             assert(f.get() == 5);
             assert(!f.valid());
+            t.join();
         }
         {
             std::promise<T> p;
             std::future<T> f = p.get_future();
-            std::thread(func4, std::move(p)).detach();
+            std::thread t(func4, std::move(p));
             try
             {
                 assert(f.valid());
@@ -113,22 +116,24 @@
                 assert(i == 3.5);
             }
             assert(!f.valid());
+            t.join();
         }
     }
     {
         typedef void T;
         {
             std::promise<T> p;
             std::future<T> f = p.get_future();
-            std::thread(func5, std::move(p)).detach();
+            std::thread t(func5, std::move(p));
             assert(f.valid());
             f.get();
             assert(!f.valid());
+            t.join();
         }
         {
             std::promise<T> p;
             std::future<T> f = p.get_future();
-            std::thread(func6, std::move(p)).detach();
+            std::thread t(func6, std::move(p));
             try
             {
                 assert(f.valid());
@@ -140,6 +145,7 @@
                 assert(i == 'c');
             }
             assert(!f.valid());
+            t.join();
         }
     }
 }
Index: test/thread/futures/futures.unique_future/wait.pass.cpp
===================================================================
--- test/thread/futures/futures.unique_future/wait.pass.cpp
+++ test/thread/futures/futures.unique_future/wait.pass.cpp
@@ -47,42 +47,45 @@
         typedef int T;
         std::promise<T> p;
         std::future<T> f = p.get_future();
-        std::thread(func1, std::move(p)).detach();
+        std::thread t(func1, std::move(p));
         assert(f.valid());
         f.wait();
         assert(f.valid());
         Clock::time_point t0 = Clock::now();
         f.wait();
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
     {
         typedef int& T;
         std::promise<T> p;
         std::future<T> f = p.get_future();
-        std::thread(func3, std::move(p)).detach();
+        std::thread t(func3, std::move(p));
         assert(f.valid());
         f.wait();
         assert(f.valid());
         Clock::time_point t0 = Clock::now();
         f.wait();
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
     {
         typedef void T;
         std::promise<T> p;
         std::future<T> f = p.get_future();
-        std::thread(func5, std::move(p)).detach();
+        std::thread t(func5, std::move(p));
         assert(f.valid());
         f.wait();
         assert(f.valid());
         Clock::time_point t0 = Clock::now();
         f.wait();
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
 }
Index: test/thread/futures/futures.unique_future/wait_for.pass.cpp
===================================================================
--- test/thread/futures/futures.unique_future/wait_for.pass.cpp
+++ test/thread/futures/futures.unique_future/wait_for.pass.cpp
@@ -50,7 +50,7 @@
         typedef int T;
         std::promise<T> p;
         std::future<T> f = p.get_future();
-        std::thread(func1, std::move(p)).detach();
+        std::thread t(func1, std::move(p));
         assert(f.valid());
         assert(f.wait_for(ms(300)) == std::future_status::timeout);
         assert(f.valid());
@@ -61,12 +61,13 @@
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(50));
+        t.join();
     }
     {
         typedef int& T;
         std::promise<T> p;
         std::future<T> f = p.get_future();
-        std::thread(func3, std::move(p)).detach();
+        std::thread t(func3, std::move(p));
         assert(f.valid());
         assert(f.wait_for(ms(300)) == std::future_status::timeout);
         assert(f.valid());
@@ -77,12 +78,13 @@
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(50));
+        t.join();
     }
     {
         typedef void T;
         std::promise<T> p;
         std::future<T> f = p.get_future();
-        std::thread(func5, std::move(p)).detach();
+        std::thread t(func5, std::move(p));
         assert(f.valid());
         assert(f.wait_for(ms(300)) == std::future_status::timeout);
         assert(f.valid());
@@ -93,5 +95,6 @@
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(50));
+        t.join();
     }
 }
Index: test/thread/futures/futures.unique_future/wait_until.pass.cpp
===================================================================
--- test/thread/futures/futures.unique_future/wait_until.pass.cpp
+++ test/thread/futures/futures.unique_future/wait_until.pass.cpp
@@ -50,7 +50,7 @@
         typedef int T;
         std::promise<T> p;
         std::future<T> f = p.get_future();
-        std::thread(func1, std::move(p)).detach();
+        std::thread t(func1, std::move(p));
         assert(f.valid());
         assert(f.wait_until(Clock::now() + ms(300)) == std::future_status::timeout);
         assert(f.valid());
@@ -61,12 +61,13 @@
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
     {
         typedef int& T;
         std::promise<T> p;
         std::future<T> f = p.get_future();
-        std::thread(func3, std::move(p)).detach();
+        std::thread t(func3, std::move(p));
         assert(f.valid());
         assert(f.wait_until(Clock::now() + ms(300)) == std::future_status::timeout);
         assert(f.valid());
@@ -77,12 +78,13 @@
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
     {
         typedef void T;
         std::promise<T> p;
         std::future<T> f = p.get_future();
-        std::thread(func5, std::move(p)).detach();
+        std::thread t(func5, std::move(p));
         assert(f.valid());
         assert(f.wait_until(Clock::now() + ms(300)) == std::future_status::timeout);
         assert(f.valid());
@@ -93,5 +95,6 @@
         Clock::time_point t1 = Clock::now();
         assert(f.valid());
         assert(t1-t0 < ms(5));
+        t.join();
     }
 }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to