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 Clock, class Duration>
19 //        bool try_join_until(const chrono::time_point<Clock, Duration>& t);
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_until(boost::chrono::steady_clock::now()+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 
86 
main()87 int main()
88 {
89   {
90     boost::thread t0( (G()));
91     BOOST_TEST(t0.joinable());
92     t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(250));
93     BOOST_TEST(!t0.joinable());
94   }
95   {
96     boost::thread t0( (th_250_ms));
97     BOOST_TEST(!t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50)));
98     t0.join();
99   }
100 
101   {
102     boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
103     boost::thread t0( resource_deadlock_would_occur_tester );
104     resource_deadlock_would_occur_th = &t0;
105     BOOST_TEST(t0.joinable());
106     lk.unlock();
107     boost::this_thread::sleep_for(boost::chrono::milliseconds(250));
108     boost::unique_lock<boost::mutex> lk2(resource_deadlock_would_occur_mtx);
109     t0.join();
110     BOOST_TEST(!t0.joinable());
111   }
112 
113   {
114     boost::thread t0( (G()));
115     t0.detach();
116     try
117     {
118       t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50));
119       BOOST_TEST(false);
120     }
121     catch (boost::system::system_error& e)
122     {
123       BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
124     }
125   }
126   {
127     boost::thread t0( (G()));
128     BOOST_TEST(t0.joinable());
129     t0.join();
130     try
131     {
132       t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50));
133       BOOST_TEST(false);
134     }
135     catch (boost::system::system_error& e)
136     {
137       BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
138     }
139 
140   }
141   {
142     boost::thread t0( (G()));
143     BOOST_TEST(t0.joinable());
144     t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(250));
145     try
146     {
147       t0.join();
148       BOOST_TEST(false);
149     }
150     catch (boost::system::system_error& e)
151     {
152       BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
153     }
154 
155   }
156 
157   return boost::report_errors();
158 }
159 
160 #else
161 #error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
162 #endif
163