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