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 // void join();
19 #define BOOST_THREAD_VESRION 3
20 #include <boost/thread/thread_only.hpp>
21 #include <boost/thread/mutex.hpp>
22 #include <boost/thread/locks.hpp>
23 #include <new>
24 #include <cstdlib>
25 #include <cassert>
26 #include <iostream>
27 #include <boost/detail/lightweight_test.hpp>
28 
29 class G
30 {
31   int alive_;
32 public:
33   static int n_alive;
34   static bool op_run;
35 
G()36   G() :
37     alive_(1)
38   {
39     ++n_alive;
40   }
G(const G & g)41   G(const G& g) :
42     alive_(g.alive_)
43   {
44     ++n_alive;
45   }
~G()46   ~G()
47   {
48     alive_ = 0;
49     --n_alive;
50   }
51 
operator ()()52   void operator()()
53   {
54     BOOST_TEST(alive_ == 1);
55     //BOOST_TEST(n_alive == 1);
56     op_run = true;
57   }
58 };
59 
60 int G::n_alive = 0;
61 bool G::op_run = false;
62 
63 boost::thread* resource_deadlock_would_occur_th=0;
64 boost::mutex resource_deadlock_would_occur_mtx;
resource_deadlock_would_occur_tester()65 void resource_deadlock_would_occur_tester()
66 {
67   try
68   {
69     boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
70     resource_deadlock_would_occur_th->join();
71     BOOST_TEST(false);
72   }
73   catch (boost::system::system_error& e)
74   {
75     BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
76   }
77   catch (...)
78   {
79     BOOST_TEST(false&&"exception thrown");
80   }
81 }
82 
main()83 int main()
84 {
85   {
86     boost::thread t0( (G()));
87     BOOST_TEST(t0.joinable());
88     t0.join();
89     BOOST_TEST(!t0.joinable());
90   }
91 
92   {
93     boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
94     boost::thread t0( resource_deadlock_would_occur_tester );
95     resource_deadlock_would_occur_th = &t0;
96     BOOST_TEST(t0.joinable());
97     lk.unlock();
98     boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
99     boost::unique_lock<boost::mutex> lk2(resource_deadlock_would_occur_mtx);
100     t0.join();
101     BOOST_TEST(!t0.joinable());
102   }
103 
104   {
105     boost::thread t0( (G()));
106     t0.detach();
107     try
108     {
109       t0.join();
110       BOOST_TEST(false);
111     }
112     catch (boost::system::system_error& e)
113     {
114       BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
115     }
116   }
117   {
118     boost::thread t0( (G()));
119     BOOST_TEST(t0.joinable());
120     t0.join();
121     try
122     {
123       t0.join();
124       BOOST_TEST(false);
125     }
126     catch (boost::system::system_error& e)
127     {
128       BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
129     }
130 
131   }
132 
133   return boost::report_errors();
134 }
135 
136