1//===----------------------------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// UNSUPPORTED: libcpp-has-no-threads 11 12// <thread> 13 14// class thread 15 16// template <class F, class ...Args> thread(F&& f, Args&&... args); 17 18// UNSUPPORTED: sanitizer-new-delete 19 20#include <thread> 21#include <new> 22#include <cstdlib> 23#include <cassert> 24 25unsigned throw_one = 0xFFFF; 26 27void* operator new(std::size_t s) throw(std::bad_alloc) 28{ 29 if (throw_one == 0) 30 throw std::bad_alloc(); 31 --throw_one; 32 return std::malloc(s); 33} 34 35void operator delete(void* p) throw() 36{ 37 std::free(p); 38} 39 40bool f_run = false; 41 42void f() 43{ 44 f_run = true; 45} 46 47class G 48{ 49 int alive_; 50public: 51 static int n_alive; 52 static bool op_run; 53 54 G() : alive_(1) {++n_alive;} 55 G(const G& g) : alive_(g.alive_) {++n_alive;} 56 ~G() {alive_ = 0; --n_alive;} 57 58 void operator()() 59 { 60 assert(alive_ == 1); 61 assert(n_alive >= 1); 62 op_run = true; 63 } 64 65 void operator()(int i, double j) 66 { 67 assert(alive_ == 1); 68 assert(n_alive >= 1); 69 assert(i == 5); 70 assert(j == 5.5); 71 op_run = true; 72 } 73}; 74 75int G::n_alive = 0; 76bool G::op_run = false; 77 78#ifndef _LIBCPP_HAS_NO_VARIADICS 79 80class MoveOnly 81{ 82 MoveOnly(const MoveOnly&); 83public: 84 MoveOnly() {} 85 MoveOnly(MoveOnly&&) {} 86 87 void operator()(MoveOnly&&) 88 { 89 } 90}; 91 92#endif 93 94int main() 95{ 96 { 97 std::thread t(f); 98 t.join(); 99 assert(f_run == true); 100 } 101 f_run = false; 102 { 103 try 104 { 105 throw_one = 0; 106 std::thread t(f); 107 assert(false); 108 } 109 catch (...) 110 { 111 throw_one = 0xFFFF; 112 assert(!f_run); 113 } 114 } 115 { 116 assert(G::n_alive == 0); 117 assert(!G::op_run); 118 std::thread t((G())); 119 t.join(); 120 assert(G::n_alive == 0); 121 assert(G::op_run); 122 } 123 G::op_run = false; 124 { 125 try 126 { 127 throw_one = 0; 128 assert(G::n_alive == 0); 129 assert(!G::op_run); 130 std::thread t((G())); 131 assert(false); 132 } 133 catch (...) 134 { 135 throw_one = 0xFFFF; 136 assert(G::n_alive == 0); 137 assert(!G::op_run); 138 } 139 } 140#ifndef _LIBCPP_HAS_NO_VARIADICS 141 { 142 assert(G::n_alive == 0); 143 assert(!G::op_run); 144 std::thread t(G(), 5, 5.5); 145 t.join(); 146 assert(G::n_alive == 0); 147 assert(G::op_run); 148 } 149 { 150 std::thread t = std::thread(MoveOnly(), MoveOnly()); 151 t.join(); 152 } 153#endif // _LIBCPP_HAS_NO_VARIADICS 154} 155