• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
21 unsigned throw_one = 0xFFFF;
22 
operator new(std::size_t s)23 void* 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 
operator delete(void * p)31 void  operator delete(void* p) throw()
32 {
33     std::free(p);
34 }
35 
36 bool f_run = false;
37 
f()38 void f()
39 {
40     f_run = true;
41 }
42 
43 class G
44 {
45     int alive_;
46 public:
47     static int n_alive;
48     static bool op_run;
49 
G()50     G() : alive_(1) {++n_alive;}
G(const G & g)51     G(const G& g) : alive_(g.alive_) {++n_alive;}
~G()52     ~G() {alive_ = 0; --n_alive;}
53 
operator ()()54     void operator()()
55     {
56         assert(alive_ == 1);
57         assert(n_alive >= 1);
58         op_run = true;
59     }
60 
operator ()(int i,double j)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 
71 int G::n_alive = 0;
72 bool G::op_run = false;
73 
74 #ifndef _LIBCPP_HAS_NO_VARIADICS
75 
76 class MoveOnly
77 {
78     MoveOnly(const MoveOnly&);
79 public:
MoveOnly()80     MoveOnly() {}
MoveOnly(MoveOnly &&)81     MoveOnly(MoveOnly&&) {}
82 
operator ()(MoveOnly &&)83     void operator()(MoveOnly&&)
84     {
85     }
86 };
87 
88 #endif
89 
main()90 int 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