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