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