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 31 #include "test_macros.h" 32 33 typedef std::chrono::high_resolution_clock Clock; 34 typedef std::chrono::milliseconds ms; 35 36 std::atomic_bool invoked{false}; 37 38 int f0() 39 { 40 invoked = true; 41 std::this_thread::sleep_for(ms(200)); 42 return 3; 43 } 44 45 int i = 0; 46 47 int& f1() 48 { 49 invoked = true; 50 std::this_thread::sleep_for(ms(200)); 51 return i; 52 } 53 54 void f2() 55 { 56 invoked = true; 57 std::this_thread::sleep_for(ms(200)); 58 } 59 60 std::unique_ptr<int> f3(int j) 61 { 62 invoked = true; 63 std::this_thread::sleep_for(ms(200)); 64 return std::unique_ptr<int>(new int(j)); 65 } 66 67 std::unique_ptr<int> f4(std::unique_ptr<int>&& p) 68 { 69 invoked = true; 70 std::this_thread::sleep_for(ms(200)); 71 return std::move(p); 72 } 73 74 void f5(int j) 75 { 76 std::this_thread::sleep_for(ms(200)); 77 ((void)j); 78 TEST_THROW(j); 79 } 80 81 template <class Ret, class CheckLambda, class... Args> 82 void test(CheckLambda&& getAndCheckFn, bool IsDeferred, Args&&... args) { 83 // Reset global state. 84 invoked = false; 85 86 // Create the future and wait 87 std::future<Ret> f = std::async(std::forward<Args>(args)...); 88 std::this_thread::sleep_for(ms(300)); 89 90 // Check that deferred async's have not invoked the function. 91 assert(invoked == !IsDeferred); 92 93 // Time the call to f.get() and check that the returned value matches 94 // what is expected. 95 Clock::time_point t0 = Clock::now(); 96 assert(getAndCheckFn(f)); 97 Clock::time_point t1 = Clock::now(); 98 99 // If the async is deferred it should take more than 100ms, otherwise 100 // it should take less than 100ms. 101 if (IsDeferred) { 102 assert(t1 - t0 > ms(100)); 103 } else { 104 assert(t1 - t0 < ms(100)); 105 } 106 } 107 108 int main(int, char**) 109 { 110 // The default launch policy is implementation defined. libc++ defines 111 // it to be std::launch::async. 112 bool DefaultPolicyIsDeferred = false; 113 bool DPID = DefaultPolicyIsDeferred; 114 115 std::launch AnyPolicy = std::launch::async | std::launch::deferred; 116 LIBCPP_ASSERT(AnyPolicy == std::launch::any); 117 118 { 119 auto checkInt = [](std::future<int>& f) { return f.get() == 3; }; 120 test<int>(checkInt, DPID, f0); 121 test<int>(checkInt, false, std::launch::async, f0); 122 test<int>(checkInt, true, std::launch::deferred, f0); 123 test<int>(checkInt, DPID, AnyPolicy, f0); 124 } 125 { 126 auto checkIntRef = [&](std::future<int&>& f) { return &f.get() == &i; }; 127 test<int&>(checkIntRef, DPID, f1); 128 test<int&>(checkIntRef, false, std::launch::async, f1); 129 test<int&>(checkIntRef, true, std::launch::deferred, f1); 130 test<int&>(checkIntRef, DPID, AnyPolicy, f1); 131 } 132 { 133 auto checkVoid = [](std::future<void>& f) { f.get(); return true; }; 134 test<void>(checkVoid, DPID, f2); 135 test<void>(checkVoid, false, std::launch::async, f2); 136 test<void>(checkVoid, true, std::launch::deferred, f2); 137 test<void>(checkVoid, DPID, AnyPolicy, f2); 138 } 139 { 140 using Ret = std::unique_ptr<int>; 141 auto checkUPtr = [](std::future<Ret>& f) { return *f.get() == 3; }; 142 test<Ret>(checkUPtr, DPID, f3, 3); 143 test<Ret>(checkUPtr, DPID, f4, std::unique_ptr<int>(new int(3))); 144 } 145 #ifndef TEST_HAS_NO_EXCEPTIONS 146 { 147 std::future<void> f = std::async(f5, 3); 148 std::this_thread::sleep_for(ms(300)); 149 try { f.get(); assert (false); } catch ( int ) {} 150 } 151 { 152 std::future<void> f = std::async(std::launch::deferred, f5, 3); 153 std::this_thread::sleep_for(ms(300)); 154 try { f.get(); assert (false); } catch ( int ) {} 155 } 156 #endif 157 return 0; 158 } 159