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()56 void f()
57 {
58   f_run = true;
59 }
60 
61 class G
62 {
63   int alive_;
64 public:
65   static int n_alive;
66   static bool op_run;
67 
G()68   G() :
69     alive_(1)
70   {
71     ++n_alive;
72   }
G(const G & g)73   G(const G& g) :
74     alive_(g.alive_)
75   {
76     ++n_alive;
77   }
~G()78   ~G()
79   {
80     alive_ = 0;
81     --n_alive;
82   }
83 
operator ()()84   void operator()()
85   {
86     BOOST_TEST(alive_ == 1);
87     //BOOST_TEST(n_alive >= 1);
88     op_run = true;
89   }
90 
91 };
92 
93 int G::n_alive = 0;
94 bool G::op_run = false;
95 
96 
main()97 int main()
98 {
99   {
100     boost::thread t(f);
101     t.join();
102     BOOST_TEST(f_run == true);
103   }
104   f_run = false;
105 #if !defined(BOOST_MSVC) && !defined(__MINGW32__)
106   {
107     try
108     {
109       throw_one = 0;
110       boost::thread t(f);
111       BOOST_TEST(false);
112     }
113     catch (...)
114     {
115       throw_one = 0xFFFF;
116       BOOST_TEST(!f_run);
117     }
118   }
119 #endif
120   {
121     BOOST_TEST(G::n_alive == 0);
122     BOOST_TEST(!G::op_run);
123     boost::thread t( (G()));
124     t.join();
125     BOOST_TEST(G::n_alive == 0);
126     BOOST_TEST(G::op_run);
127   }
128 #if !defined(BOOST_MSVC) && !defined(__MINGW32__)
129   G::op_run = false;
130   {
131     try
132     {
133       throw_one = 0;
134       BOOST_TEST(G::n_alive == 0);
135       BOOST_TEST(!G::op_run);
136       boost::thread t( (G()));
137       BOOST_TEST(false);
138     }
139     catch (...)
140     {
141       throw_one = 0xFFFF;
142       BOOST_TEST(G::n_alive == 0);
143       std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
144       BOOST_TEST(!G::op_run);
145     }
146   }
147 #endif
148 
149   return boost::report_errors();
150 }
151