]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/test/test_future_post.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / fiber / test / test_future_post.cpp
1 // (C) Copyright 2008-10 Anthony Williams
2 // 2015 Oliver Kowalke
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7
8 #include <chrono>
9 #include <memory>
10 #include <stdexcept>
11 #include <string>
12 #include <utility>
13
14 #include <boost/test/unit_test.hpp>
15
16 #include <boost/fiber/all.hpp>
17
18 typedef std::chrono::milliseconds ms;
19 typedef std::chrono::high_resolution_clock Clock;
20
21 int gi = 7;
22
23 struct my_exception : public std::runtime_error {
24 my_exception() :
25 std::runtime_error("my_exception") {
26 }
27 };
28
29 struct A {
30 A() = default;
31
32 A( A const&) = delete;
33 A( A &&) = default;
34
35 A & operator=( A const&) = delete;
36 A & operator=( A &&) = default;
37
38 int value;
39 };
40
41 void fn1( boost::fibers::promise< int > * p, int i) {
42 boost::this_fiber::yield();
43 p->set_value( i);
44 }
45
46 void fn2() {
47 boost::fibers::promise< int > p;
48 boost::fibers::future< int > f( p.get_future() );
49 boost::this_fiber::yield();
50 boost::fibers::fiber( boost::fibers::launch::post, fn1, & p, 7).detach();
51 boost::this_fiber::yield();
52 BOOST_CHECK( 7 == f.get() );
53 }
54
55 int fn3() {
56 return 3;
57 }
58
59 void fn4() {
60 }
61
62 int fn5() {
63 boost::throw_exception( my_exception() );
64 return 3;
65 }
66
67 void fn6() {
68 boost::throw_exception( my_exception() );
69 }
70
71 int & fn7() {
72 return gi;
73 }
74
75 int fn8( int i) {
76 return i;
77 }
78
79 A fn9() {
80 A a;
81 a.value = 3;
82 return std::move( a);
83 }
84
85 A fn10() {
86 boost::throw_exception( my_exception() );
87 return A();
88 }
89
90 void fn11( boost::fibers::promise< int > p) {
91 boost::this_fiber::sleep_for( ms(500) );
92 p.set_value(3);
93 }
94
95 void fn12( boost::fibers::promise< int& > p) {
96 boost::this_fiber::sleep_for( ms(500) );
97 gi = 5;
98 p.set_value( gi);
99 }
100
101 void fn13( boost::fibers::promise< void > p) {
102 boost::this_fiber::sleep_for( ms(500) );
103 p.set_value();
104 }
105
106 // future
107 void test_future_create() {
108 // default constructed future is not valid
109 boost::fibers::future< int > f1;
110 BOOST_CHECK( ! f1.valid() );
111
112 // future retrieved from promise is valid (if it is the first)
113 boost::fibers::promise< int > p2;
114 boost::fibers::future< int > f2 = p2.get_future();
115 BOOST_CHECK( f2.valid() );
116 }
117
118 void test_future_create_ref() {
119 // default constructed future is not valid
120 boost::fibers::future< int& > f1;
121 BOOST_CHECK( ! f1.valid() );
122
123 // future retrieved from promise is valid (if it is the first)
124 boost::fibers::promise< int& > p2;
125 boost::fibers::future< int& > f2 = p2.get_future();
126 BOOST_CHECK( f2.valid() );
127 }
128
129 void test_future_create_void() {
130 // default constructed future is not valid
131 boost::fibers::future< void > f1;
132 BOOST_CHECK( ! f1.valid() );
133
134 // future retrieved from promise is valid (if it is the first)
135 boost::fibers::promise< void > p2;
136 boost::fibers::future< void > f2 = p2.get_future();
137 BOOST_CHECK( f2.valid() );
138 }
139
140 void test_future_move() {
141 // future retrieved from promise is valid (if it is the first)
142 boost::fibers::promise< int > p1;
143 boost::fibers::future< int > f1 = p1.get_future();
144 BOOST_CHECK( f1.valid() );
145
146 // move construction
147 boost::fibers::future< int > f2( std::move( f1) );
148 BOOST_CHECK( ! f1.valid() );
149 BOOST_CHECK( f2.valid() );
150
151 // move assignment
152 f1 = std::move( f2);
153 BOOST_CHECK( f1.valid() );
154 BOOST_CHECK( ! f2.valid() );
155 }
156
157 void test_future_move_ref() {
158 // future retrieved from promise is valid (if it is the first)
159 boost::fibers::promise< int& > p1;
160 boost::fibers::future< int& > f1 = p1.get_future();
161 BOOST_CHECK( f1.valid() );
162
163 // move construction
164 boost::fibers::future< int& > f2( std::move( f1) );
165 BOOST_CHECK( ! f1.valid() );
166 BOOST_CHECK( f2.valid() );
167
168 // move assignment
169 f1 = std::move( f2);
170 BOOST_CHECK( f1.valid() );
171 BOOST_CHECK( ! f2.valid() );
172 }
173
174 void test_future_move_void() {
175 // future retrieved from promise is valid (if it is the first)
176 boost::fibers::promise< void > p1;
177 boost::fibers::future< void > f1 = p1.get_future();
178 BOOST_CHECK( f1.valid() );
179
180 // move construction
181 boost::fibers::future< void > f2( std::move( f1) );
182 BOOST_CHECK( ! f1.valid() );
183 BOOST_CHECK( f2.valid() );
184
185 // move assignment
186 f1 = std::move( f2);
187 BOOST_CHECK( f1.valid() );
188 BOOST_CHECK( ! f2.valid() );
189 }
190
191 void test_future_get() {
192 // future retrieved from promise is valid (if it is the first)
193 boost::fibers::promise< int > p1;
194 p1.set_value( 7);
195
196 boost::fibers::future< int > f1 = p1.get_future();
197 BOOST_CHECK( f1.valid() );
198
199 // get
200 BOOST_CHECK( ! f1.get_exception_ptr() );
201 BOOST_CHECK( 7 == f1.get() );
202 BOOST_CHECK( ! f1.valid() );
203
204 // throw broken_promise if promise is destroyed without set
205 {
206 boost::fibers::promise< int > p2;
207 f1 = p2.get_future();
208 }
209 bool thrown = false;
210 try {
211 f1.get();
212 } catch ( boost::fibers::broken_promise const&) {
213 thrown = true;
214 }
215 BOOST_CHECK( ! f1.valid() );
216 BOOST_CHECK( thrown);
217 }
218
219 void test_future_get_move() {
220 // future retrieved from promise is valid (if it is the first)
221 boost::fibers::promise< A > p1;
222 A a; a.value = 7;
223 p1.set_value( std::move( a) );
224
225 boost::fibers::future< A > f1 = p1.get_future();
226 BOOST_CHECK( f1.valid() );
227
228 // get
229 BOOST_CHECK( ! f1.get_exception_ptr() );
230 BOOST_CHECK( 7 == f1.get().value);
231 BOOST_CHECK( ! f1.valid() );
232
233 // throw broken_promise if promise is destroyed without set
234 {
235 boost::fibers::promise< A > p2;
236 f1 = p2.get_future();
237 }
238 bool thrown = false;
239 try {
240 f1.get();
241 } catch ( boost::fibers::broken_promise const&) {
242 thrown = true;
243 }
244 BOOST_CHECK( ! f1.valid() );
245 BOOST_CHECK( thrown);
246 }
247
248 void test_future_get_ref() {
249 // future retrieved from promise is valid (if it is the first)
250 boost::fibers::promise< int& > p1;
251 int i = 7;
252 p1.set_value( i);
253
254 boost::fibers::future< int& > f1 = p1.get_future();
255 BOOST_CHECK( f1.valid() );
256
257 // get
258 BOOST_CHECK( ! f1.get_exception_ptr() );
259 int & j = f1.get();
260 BOOST_CHECK( &i == &j);
261 BOOST_CHECK( ! f1.valid() );
262
263 // throw broken_promise if promise is destroyed without set
264 {
265 boost::fibers::promise< int& > p2;
266 f1 = p2.get_future();
267 }
268 bool thrown = false;
269 try {
270 f1.get();
271 } catch ( boost::fibers::broken_promise const&) {
272 thrown = true;
273 }
274 BOOST_CHECK( ! f1.valid() );
275 BOOST_CHECK( thrown);
276 }
277
278
279 void test_future_get_void() {
280 // future retrieved from promise is valid (if it is the first)
281 boost::fibers::promise< void > p1;
282 p1.set_value();
283
284 boost::fibers::future< void > f1 = p1.get_future();
285 BOOST_CHECK( f1.valid() );
286
287 // get
288 BOOST_CHECK( ! f1.get_exception_ptr() );
289 f1.get();
290 BOOST_CHECK( ! f1.valid() );
291
292 // throw broken_promise if promise is destroyed without set
293 {
294 boost::fibers::promise< void > p2;
295 f1 = p2.get_future();
296 }
297 bool thrown = false;
298 try {
299 f1.get();
300 } catch ( boost::fibers::broken_promise const&) {
301 thrown = true;
302 }
303 BOOST_CHECK( ! f1.valid() );
304 BOOST_CHECK( thrown);
305 }
306
307 void test_future_share() {
308 // future retrieved from promise is valid (if it is the first)
309 boost::fibers::promise< int > p1;
310 int i = 7;
311 p1.set_value( i);
312
313 boost::fibers::future< int > f1 = p1.get_future();
314 BOOST_CHECK( f1.valid() );
315
316 // share
317 boost::fibers::shared_future< int > sf1 = f1.share();
318 BOOST_CHECK( sf1.valid() );
319 BOOST_CHECK( ! f1.valid() );
320
321 // get
322 BOOST_CHECK( ! sf1.get_exception_ptr() );
323 int j = sf1.get();
324 BOOST_CHECK_EQUAL( i, j);
325 BOOST_CHECK( sf1.valid() );
326 }
327
328 void test_future_share_ref() {
329 // future retrieved from promise is valid (if it is the first)
330 boost::fibers::promise< int& > p1;
331 int i = 7;
332 p1.set_value( i);
333
334 boost::fibers::future< int& > f1 = p1.get_future();
335 BOOST_CHECK( f1.valid() );
336
337 // share
338 boost::fibers::shared_future< int& > sf1 = f1.share();
339 BOOST_CHECK( sf1.valid() );
340 BOOST_CHECK( ! f1.valid() );
341
342 // get
343 BOOST_CHECK( ! sf1.get_exception_ptr() );
344 int & j = sf1.get();
345 BOOST_CHECK( &i == &j);
346 BOOST_CHECK( sf1.valid() );
347 }
348
349 void test_future_share_void() {
350 // future retrieved from promise is valid (if it is the first)
351 boost::fibers::promise< void > p1;
352 p1.set_value();
353
354 boost::fibers::future< void > f1 = p1.get_future();
355 BOOST_CHECK( f1.valid() );
356
357 // share
358 boost::fibers::shared_future< void > sf1 = f1.share();
359 BOOST_CHECK( sf1.valid() );
360 BOOST_CHECK( ! f1.valid() );
361
362 // get
363 BOOST_CHECK( ! sf1.get_exception_ptr() );
364 sf1.get();
365 BOOST_CHECK( sf1.valid() );
366 }
367
368 void test_future_wait() {
369 // future retrieved from promise is valid (if it is the first)
370 boost::fibers::promise< int > p1;
371 boost::fibers::future< int > f1 = p1.get_future();
372
373 // wait on future
374 p1.set_value( 7);
375 f1.wait();
376 BOOST_CHECK( 7 == f1.get() );
377 }
378
379 void test_future_wait_ref() {
380 // future retrieved from promise is valid (if it is the first)
381 boost::fibers::promise< int& > p1;
382 boost::fibers::future< int& > f1 = p1.get_future();
383
384 // wait on future
385 int i = 7;
386 p1.set_value( i);
387 f1.wait();
388 int & j = f1.get();
389 BOOST_CHECK( &i == &j);
390 }
391
392 void test_future_wait_void() {
393 // future retrieved from promise is valid (if it is the first)
394 boost::fibers::promise< void > p1;
395 boost::fibers::future< void > f1 = p1.get_future();
396
397 // wait on future
398 p1.set_value();
399 f1.wait();
400 f1.get();
401 BOOST_CHECK( ! f1.valid() );
402 }
403
404 void test_future_wait_for() {
405 // future retrieved from promise is valid (if it is the first)
406 boost::fibers::promise< int > p1;
407 boost::fibers::future< int > f1 = p1.get_future();
408
409 boost::fibers::fiber( boost::fibers::launch::post, fn11, std::move( p1) ).detach();
410
411 // wait on future
412 BOOST_CHECK( f1.valid() );
413 boost::fibers::future_status status = f1.wait_for( ms(300) );
414 BOOST_CHECK( boost::fibers::future_status::timeout == status);
415
416 BOOST_CHECK( f1.valid() );
417 status = f1.wait_for( ms(300) );
418 BOOST_CHECK( boost::fibers::future_status::ready == status);
419
420 BOOST_CHECK( f1.valid() );
421 f1.wait();
422 }
423
424 void test_future_wait_for_ref() {
425 // future retrieved from promise is valid (if it is the first)
426 boost::fibers::promise< int& > p1;
427 boost::fibers::future< int& > f1 = p1.get_future();
428
429 boost::fibers::fiber( boost::fibers::launch::post, fn12, std::move( p1) ).detach();
430
431 // wait on future
432 BOOST_CHECK( f1.valid() );
433 boost::fibers::future_status status = f1.wait_for( ms(300) );
434 BOOST_CHECK( boost::fibers::future_status::timeout == status);
435
436 BOOST_CHECK( f1.valid() );
437 status = f1.wait_for( ms(300) );
438 BOOST_CHECK( boost::fibers::future_status::ready == status);
439
440 BOOST_CHECK( f1.valid() );
441 f1.wait();
442 }
443
444 void test_future_wait_for_void() {
445 // future retrieved from promise is valid (if it is the first)
446 boost::fibers::promise< void > p1;
447 boost::fibers::future< void > f1 = p1.get_future();
448
449 boost::fibers::fiber( boost::fibers::launch::post, fn13, std::move( p1) ).detach();
450
451 // wait on future
452 BOOST_CHECK( f1.valid() );
453 boost::fibers::future_status status = f1.wait_for( ms(300) );
454 BOOST_CHECK( boost::fibers::future_status::timeout == status);
455
456 BOOST_CHECK( f1.valid() );
457 status = f1.wait_for( ms(300) );
458 BOOST_CHECK( boost::fibers::future_status::ready == status);
459
460 BOOST_CHECK( f1.valid() );
461 f1.wait();
462 }
463
464 void test_future_wait_until() {
465 // future retrieved from promise is valid (if it is the first)
466 boost::fibers::promise< int > p1;
467 boost::fibers::future< int > f1 = p1.get_future();
468
469 boost::fibers::fiber( boost::fibers::launch::post, fn11, std::move( p1) ).detach();
470
471 // wait on future
472 BOOST_CHECK( f1.valid() );
473 boost::fibers::future_status status = f1.wait_until( Clock::now() + ms(300) );
474 BOOST_CHECK( boost::fibers::future_status::timeout == status);
475
476 BOOST_CHECK( f1.valid() );
477 status = f1.wait_until( Clock::now() + ms(300) );
478 BOOST_CHECK( boost::fibers::future_status::ready == status);
479
480 BOOST_CHECK( f1.valid() );
481 f1.wait();
482 }
483
484 void test_future_wait_until_ref() {
485 // future retrieved from promise is valid (if it is the first)
486 boost::fibers::promise< int& > p1;
487 boost::fibers::future< int& > f1 = p1.get_future();
488
489 boost::fibers::fiber( boost::fibers::launch::post, fn12, std::move( p1) ).detach();
490
491 // wait on future
492 BOOST_CHECK( f1.valid() );
493 boost::fibers::future_status status = f1.wait_until( Clock::now() + ms(300) );
494 BOOST_CHECK( boost::fibers::future_status::timeout == status);
495
496 BOOST_CHECK( f1.valid() );
497 status = f1.wait_until( Clock::now() + ms(300) );
498 BOOST_CHECK( boost::fibers::future_status::ready == status);
499
500 BOOST_CHECK( f1.valid() );
501 f1.wait();
502 }
503
504 void test_future_wait_until_void() {
505 // future retrieved from promise is valid (if it is the first)
506 boost::fibers::promise< void > p1;
507 boost::fibers::future< void > f1 = p1.get_future();
508
509 boost::fibers::fiber( boost::fibers::launch::post, fn13, std::move( p1) ).detach();
510
511 // wait on future
512 BOOST_CHECK( f1.valid() );
513 boost::fibers::future_status status = f1.wait_until( Clock::now() + ms(300) );
514 BOOST_CHECK( boost::fibers::future_status::timeout == status);
515
516 BOOST_CHECK( f1.valid() );
517 status = f1.wait_until( Clock::now() + ms(300) );
518 BOOST_CHECK( boost::fibers::future_status::ready == status);
519
520 BOOST_CHECK( f1.valid() );
521 f1.wait();
522 }
523
524 void test_future_wait_with_fiber_1() {
525 boost::fibers::promise< int > p1;
526 boost::fibers::fiber( boost::fibers::launch::post, fn1, & p1, 7).detach();
527
528 boost::fibers::future< int > f1 = p1.get_future();
529
530 // wait on future
531 BOOST_CHECK( 7 == f1.get() );
532 }
533
534 void test_future_wait_with_fiber_2() {
535 boost::fibers::fiber( boost::fibers::launch::post, fn2).join();
536 }
537
538
539 boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) {
540 boost::unit_test_framework::test_suite* test =
541 BOOST_TEST_SUITE("Boost.Fiber: future test suite");
542
543 test->add(BOOST_TEST_CASE(test_future_create));
544 test->add(BOOST_TEST_CASE(test_future_create_ref));
545 test->add(BOOST_TEST_CASE(test_future_create_void));
546 test->add(BOOST_TEST_CASE(test_future_move));
547 test->add(BOOST_TEST_CASE(test_future_move_ref));
548 test->add(BOOST_TEST_CASE(test_future_move_void));
549 test->add(BOOST_TEST_CASE(test_future_get));
550 test->add(BOOST_TEST_CASE(test_future_get_move));
551 test->add(BOOST_TEST_CASE(test_future_get_ref));
552 test->add(BOOST_TEST_CASE(test_future_get_void));
553 test->add(BOOST_TEST_CASE(test_future_share));
554 test->add(BOOST_TEST_CASE(test_future_share_ref));
555 test->add(BOOST_TEST_CASE(test_future_share_void));
556 test->add(BOOST_TEST_CASE(test_future_wait));
557 test->add(BOOST_TEST_CASE(test_future_wait_ref));
558 test->add(BOOST_TEST_CASE(test_future_wait_void));
559 test->add(BOOST_TEST_CASE(test_future_wait_for));
560 test->add(BOOST_TEST_CASE(test_future_wait_for_ref));
561 test->add(BOOST_TEST_CASE(test_future_wait_for_void));
562 test->add(BOOST_TEST_CASE(test_future_wait_until));
563 test->add(BOOST_TEST_CASE(test_future_wait_until_ref));
564 test->add(BOOST_TEST_CASE(test_future_wait_until_void));
565 test->add(BOOST_TEST_CASE(test_future_wait_with_fiber_1));
566 test->add(BOOST_TEST_CASE(test_future_wait_with_fiber_2));
567
568 return test;
569 }