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 // Copyright (C) 2011 Vicente J. Botet Escriba
10 //
11 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
12 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
13 
14 // <boost/thread/thread.hpp>
15 
16 // class thread
17 
18 // template <class F, class ...Args> thread(F f, Args... args);
19 
20 #include <new>
21 #include <cstdlib>
22 #include <cassert>
23 #include <boost/thread/thread_only.hpp>
24 #include <boost/detail/lightweight_test.hpp>
25 
26 unsigned throw_one = 0xFFFF;
27 
28 #if defined _GLIBCXX_THROW
operator new(std::size_t s)29 void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
30 #elif defined BOOST_MSVC
31 void* operator new(std::size_t s)
32 #elif __cplusplus > 201402L
33 void* operator new(std::size_t s)
34 #else
35 void* operator new(std::size_t s) throw (std::bad_alloc)
36 #endif
37 {
38   //std::cout << __FILE__ << ":" << __LINE__ << std::endl;
39   if (throw_one == 0) throw std::bad_alloc();
40   --throw_one;
41   return std::malloc(s);
42 }
43 
44 #if defined BOOST_MSVC
operator delete(void * p)45 void operator delete(void* p)
46 #else
47 void operator delete(void* p) BOOST_NOEXCEPT_OR_NOTHROW
48 #endif
49 {
50   //std::cout << __FILE__ << ":" << __LINE__ << std::endl;
51   std::free(p);
52 }
53 
54 bool f_run = false;
55 
f(int i,double j)56 void f(int i, double j)
57 {
58   BOOST_TEST(i == 5);
59   BOOST_TEST(j == 5.5);
60   f_run = true;
61 }
62 
63 class G
64 {
65   int alive_;
66 public:
67   static int n_alive;
68   static bool op_run;
69 
G()70   G() :
71     alive_(1)
72   {
73     ++n_alive;
74   }
G(const G & g)75   G(const G& g) :
76     alive_(g.alive_)
77   {
78     ++n_alive;
79   }
~G()80   ~G()
81   {
82     alive_ = 0;
83     --n_alive;
84   }
85 
operator ()(int i,double j)86   void operator()(int i, double j)
87   {
88     BOOST_TEST(alive_ == 1);
89     //BOOST_TEST(n_alive >= 1);
90     BOOST_TEST(i == 5);
91     BOOST_TEST(j == 5.5);
92     op_run = true;
93   }
94 };
95 
96 int G::n_alive = 0;
97 bool G::op_run = false;
98 
99 
main()100 int main()
101 {
102   {
103     std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
104     boost::thread t(f, 5, 5.5);
105     t.join();
106     BOOST_TEST(f_run == true);
107     std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
108   }
109 #if !defined(BOOST_MSVC) && !defined(__MINGW32__)
110   f_run = false;
111   {
112     std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
113     try
114     {
115       std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
116       throw_one = 0;
117       boost::thread t(f, 5, 5.5);
118       BOOST_TEST(false);
119       std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
120     }
121     catch (...)
122     {
123       std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
124       throw_one = 0xFFFF;
125       BOOST_TEST(!f_run);
126       std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
127     }
128     std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
129   }
130 #endif
131   {
132     std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
133     BOOST_TEST(G::n_alive == 0);
134     std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
135     BOOST_TEST(!G::op_run);
136     boost::thread t(G(), 5, 5.5);
137     t.join();
138     std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
139     BOOST_TEST(G::n_alive == 0);
140     BOOST_TEST(G::op_run);
141     std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
142   }
143 
144   return boost::report_errors();
145 }
146