1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // UNSUPPORTED: no-threads 10 // UNSUPPORTED: c++03 11 12 // ALLOW_RETRIES: 3 13 14 // <future> 15 16 // template <class F, class... Args> 17 // future<typename result_of<F(Args...)>::type> 18 // async(F&& f, Args&&... args); 19 20 // template <class F, class... Args> 21 // future<typename result_of<F(Args...)>::type> 22 // async(launch policy, F&& f, Args&&... args); 23 24 25 #include <atomic> 26 #include <cassert> 27 #include <chrono> 28 #include <future> 29 #include <memory> 30 #include <thread> 31 32 #include "test_macros.h" 33 34 typedef std::chrono::high_resolution_clock Clock; 35 typedef std::chrono::milliseconds ms; 36 37 std::atomic_bool invoked{false}; 38 39 int f0() 40 { 41 invoked = true; 42 std::this_thread::sleep_for(ms(200)); 43 return 3; 44 } 45 46 int i = 0; 47 48 int& f1() 49 { 50 invoked = true; 51 std::this_thread::sleep_for(ms(200)); 52 return i; 53 } 54 55 void f2() 56 { 57 invoked = true; 58 std::this_thread::sleep_for(ms(200)); 59 } 60 61 std::unique_ptr<int> f3(int j) 62 { 63 invoked = true; 64 std::this_thread::sleep_for(ms(200)); 65 return std::unique_ptr<int>(new int(j)); 66 } 67 68 std::unique_ptr<int> f4(std::unique_ptr<int>&& p) 69 { 70 invoked = true; 71 std::this_thread::sleep_for(ms(200)); 72 return std::move(p); 73 } 74 75 void f5(int j) 76 { 77 std::this_thread::sleep_for(ms(200)); 78 ((void)j); 79 TEST_THROW(j); 80 } 81 82 template <class Ret, class CheckLambda, class... Args> 83 void test(CheckLambda&& getAndCheckFn, bool IsDeferred, Args&&... args) { 84 // Reset global state. 85 invoked = false; 86 87 // Create the future and wait 88 std::future<Ret> f = std::async(std::forward<Args>(args)...); 89 std::this_thread::sleep_for(ms(300)); 90 91 // Check that deferred async's have not invoked the function. 92 assert(invoked == !IsDeferred); 93 94 // Time the call to f.get() and check that the returned value matches 95 // what is expected. 96 Clock::time_point t0 = Clock::now(); 97 assert(getAndCheckFn(f)); 98 Clock::time_point t1 = Clock::now(); 99 100 // If the async is deferred it should take more than 100ms, otherwise 101 // it should take less than 100ms. 102 if (IsDeferred) { 103 assert(t1 - t0 > ms(100)); 104 } else { 105 assert(t1 - t0 < ms(100)); 106 } 107 } 108 109 int main(int, char**) 110 { 111 // The default launch policy is implementation defined. libc++ defines 112 // it to be std::launch::async. 113 bool DefaultPolicyIsDeferred = false; 114 bool DPID = DefaultPolicyIsDeferred; 115 116 std::launch AnyPolicy = std::launch::async | std::launch::deferred; 117 LIBCPP_ASSERT(AnyPolicy == std::launch::any); 118 119 { 120 auto checkInt = [](std::future<int>& f) { return f.get() == 3; }; 121 test<int>(checkInt, DPID, f0); 122 test<int>(checkInt, false, std::launch::async, f0); 123 test<int>(checkInt, true, std::launch::deferred, f0); 124 test<int>(checkInt, DPID, AnyPolicy, f0); 125 } 126 { 127 auto checkIntRef = [&](std::future<int&>& f) { return &f.get() == &i; }; 128 test<int&>(checkIntRef, DPID, f1); 129 test<int&>(checkIntRef, false, std::launch::async, f1); 130 test<int&>(checkIntRef, true, std::launch::deferred, f1); 131 test<int&>(checkIntRef, DPID, AnyPolicy, f1); 132 } 133 { 134 auto checkVoid = [](std::future<void>& f) { f.get(); return true; }; 135 test<void>(checkVoid, DPID, f2); 136 test<void>(checkVoid, false, std::launch::async, f2); 137 test<void>(checkVoid, true, std::launch::deferred, f2); 138 test<void>(checkVoid, DPID, AnyPolicy, f2); 139 } 140 { 141 using Ret = std::unique_ptr<int>; 142 auto checkUPtr = [](std::future<Ret>& f) { return *f.get() == 3; }; 143 test<Ret>(checkUPtr, DPID, f3, 3); 144 test<Ret>(checkUPtr, DPID, f4, std::unique_ptr<int>(new int(3))); 145 } 146 #ifndef TEST_HAS_NO_EXCEPTIONS 147 { 148 std::future<void> f = std::async(f5, 3); 149 std::this_thread::sleep_for(ms(300)); 150 try { f.get(); assert (false); } catch ( int ) {} 151 } 152 { 153 std::future<void> f = std::async(std::launch::deferred, f5, 3); 154 std::this_thread::sleep_for(ms(300)); 155 try { f.get(); assert (false); } catch ( int ) {} 156 } 157 #endif 158 return 0; 159 } 160