1 // Copyright (C) 2014-2015 Vicente J. Botet Escriba
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 // <boost/thread/experimental/parallel/v1/exception_list.hpp>
7
8
9 #define BOOST_THREAD_VERSION 4
10 #define BOOST_THREAD_PROVIDES_EXECUTORS
11 #include <boost/config.hpp>
12 #if ! defined BOOST_NO_CXX11_DECLTYPE
13 #define BOOST_RESULT_OF_USE_DECLTYPE
14 #endif
15
16 #include <boost/thread/experimental/parallel/v2/task_region.hpp>
17 #include <string>
18
19 #include <boost/detail/lightweight_test.hpp>
20
21 #if ! defined BOOST_NO_CXX11_LAMBDAS && defined(BOOST_THREAD_PROVIDES_INVOKE)
22 using boost::experimental::parallel::v2::task_region;
23 using boost::experimental::parallel::v2::task_region_handle;
24 using boost::experimental::parallel::v1::exception_list;
25
run_no_exception()26 void run_no_exception()
27 {
28 std::string s("test");
29 bool parent_flag = false;
30 bool task1_flag = false;
31 bool task2_flag = false;
32 bool task21_flag = false;
33 bool task3_flag = false;
34 task_region([&](task_region_handle& trh)
35 {
36 parent_flag = true;
37 trh.run([&]()
38 {
39 task1_flag = true;
40 std::cout << "task1: " << s << std::endl;
41 });
42 trh.run([&]()
43 {
44 task2_flag = true;
45 std::cout << "task2" << std::endl;
46 task_region([&](task_region_handle& trh)
47 {
48 trh.run([&]()
49 {
50 task21_flag = true;
51 std::cout << "task2.1" << std::endl;
52 });
53 });
54 });
55 int i = 0, j = 10, k = 20;
56 trh.run([=, &task3_flag]()
57 {
58 task3_flag = true;
59 std::cout << "task3: " << i << " " << j << " " << k << std::endl;
60 });
61 std::cout << "parent" << std::endl;
62 });
63 BOOST_TEST(parent_flag);
64 BOOST_TEST(task1_flag);
65 BOOST_TEST(task2_flag);
66 BOOST_TEST(task21_flag);
67 BOOST_TEST(task3_flag);
68 }
69
run_no_exception_wait()70 void run_no_exception_wait()
71 {
72 std::string s("test");
73 bool parent_flag = false;
74 bool wait_flag = false;
75 bool task1_flag = false;
76 bool task2_flag = false;
77 bool task21_flag = false;
78 bool task3_flag = false;
79 task_region([&](task_region_handle& trh)
80 {
81 parent_flag = true;
82 trh.run([&]()
83 {
84 task1_flag = true;
85 std::cout << "task1: " << s << std::endl;
86 });
87 trh.run([&]()
88 {
89 task2_flag = true;
90 std::cout << "task2" << std::endl;
91 task_region([&](task_region_handle& trh)
92 {
93 trh.run([&]()
94 {
95 task21_flag = true;
96 std::cout << "task2.1" << std::endl;
97 });
98 });
99 });
100 int i = 0, j = 10, k = 20;
101 trh.run([=, &task3_flag]()
102 {
103 task3_flag = true;
104 std::cout << "task3: " << i << " " << j << " " << k << std::endl;
105 });
106 std::cout << "before" << std::endl;
107 trh.wait();
108 wait_flag = true;
109 std::cout << "parent" << std::endl;
110 });
111 BOOST_TEST(parent_flag);
112 BOOST_TEST(wait_flag);
113 BOOST_TEST(task1_flag);
114 BOOST_TEST(task2_flag);
115 BOOST_TEST(task21_flag);
116 BOOST_TEST(task3_flag);
117 }
118
run_exception_1()119 void run_exception_1()
120 {
121 try
122 {
123 task_region([](task_region_handle& trh)
124 {
125 trh.run([]()
126 {
127 std::cout << "task1" << std::endl;
128 throw 1;
129 });
130 boost::this_thread::sleep_for(boost::chrono::seconds(1));
131 trh.run([]()
132 {
133 std::cout << "task3" << std::endl;
134 });
135 #if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
136 BOOST_TEST(false);
137 #endif
138 });
139 BOOST_TEST(false);
140 }
141 catch (exception_list const& e)
142 {
143 BOOST_TEST_EQ(e.size(), 1u);
144 }
145 catch (...)
146 {
147 BOOST_TEST(false);
148 }
149 }
150
run_exception()151 void run_exception()
152 {
153 try
154 {
155 task_region([](task_region_handle& trh)
156 {
157 trh.run([]()
158 {
159 std::cout << "task1" << std::endl;
160 throw 1;
161 });
162 trh.run([]()
163 {
164 std::cout << "task2" << std::endl;
165 throw 2;
166 });
167 boost::this_thread::sleep_for(boost::chrono::seconds(1));
168 trh.run([]()
169 {
170 std::cout << "task3" << std::endl;
171 throw 3;
172 });
173 std::cout << "parent" << std::endl;
174 throw 100;
175 });
176 BOOST_TEST(false);
177 }
178 catch (exception_list const& el)
179 {
180 BOOST_TEST(el.size() >= 1u);
181 for (boost::exception_ptr const& e: el)
182 {
183 try {
184 boost::rethrow_exception(e);
185 }
186 catch (boost::exception&)
187 {
188 BOOST_TEST(true);
189 }
190 catch (int i) // this doesn't works yet
191 {
192 BOOST_TEST((i == 1) || (i == 2) || (i == 3));
193 }
194 catch (...)
195 {
196 BOOST_TEST(false);
197 }
198 }
199 }
200 catch (...)
201 {
202 BOOST_TEST(false);
203 }
204 }
205
206
run_nested_exception()207 void run_nested_exception()
208 {
209 std::string s("test");
210 bool parent_flag = false;
211 bool task1_flag = false;
212 bool task2_flag = false;
213 bool task21_flag = false;
214 bool task3_flag = false;
215 try
216 {
217 task_region([&](task_region_handle& trh)
218 {
219 parent_flag = true;
220 trh.run([&]()
221 {
222 task1_flag = true;
223 std::cout << "task1: " << s << std::endl;
224 });
225 trh.run([&]()
226 {
227 task2_flag = true;
228 std::cout << "task2" << std::endl;
229 task_region([&](task_region_handle& trh)
230 {
231 trh.run([&]()
232 {
233 task21_flag = true;
234 std::cout << "task2.1" << std::endl;
235 throw 21;
236 });
237 });
238 });
239 int i = 0, j = 10, k = 20;
240 trh.run([=, &task3_flag]()
241 {
242 task3_flag = true;
243 std::cout << "task3: " << i << " " << j << " " << k << std::endl;
244 });
245 std::cout << "parent" << std::endl;
246 });
247 }
248 catch (exception_list const& el)
249 {
250 BOOST_TEST(el.size() == 1u);
251 for (boost::exception_ptr const& e: el)
252 {
253 try {
254 boost::rethrow_exception(e);
255 }
256 catch (int i) // this doesn't works yet
257 {
258 BOOST_TEST_EQ(i, 21);
259 }
260 catch (boost::exception&)
261 {
262 BOOST_TEST(true);
263 }
264 catch (...)
265 {
266 BOOST_TEST(false);
267 }
268 }
269 }
270 catch (...)
271 {
272 BOOST_TEST(false);
273 }
274 BOOST_TEST(parent_flag);
275 BOOST_TEST(task1_flag);
276 BOOST_TEST(task2_flag);
277 BOOST_TEST(task21_flag);
278 }
279
280
main()281 int main()
282 {
283 run_no_exception();
284 run_no_exception_wait();
285 run_exception();
286 run_exception_1();
287 run_nested_exception();
288 return boost::report_errors();
289 }
290 #else
main()291 int main()
292 {
293 return boost::report_errors();
294 }
295 #endif
296