]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/fiber/test/test_future_dispatch.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / fiber / test / test_future_dispatch.cpp
CommitLineData
7c673cae
FG
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
18typedef std::chrono::milliseconds ms;
19typedef std::chrono::high_resolution_clock Clock;
20
21int gi = 7;
22
23struct my_exception : public std::runtime_error {
24 my_exception() :
25 std::runtime_error("my_exception") {
26 }
27};
28
29struct 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
41void fn1( boost::fibers::promise< int > * p, int i) {
42 boost::this_fiber::yield();
43 p->set_value( i);
44}
45
46void 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::dispatch, fn1, & p, 7).detach();
51 boost::this_fiber::yield();
52 BOOST_CHECK( 7 == f.get() );
53}
54
55int fn3() {
56 return 3;
57}
58
59void fn4() {
60}
61
62int fn5() {
63 boost::throw_exception( my_exception() );
64 return 3;
65}
66
67void fn6() {
68 boost::throw_exception( my_exception() );
69}
70
71int & fn7() {
72 return gi;
73}
74
75int fn8( int i) {
76 return i;
77}
78
79A fn9() {
80 A a;
81 a.value = 3;
b32b8144 82 return a;
7c673cae
FG
83}
84
85A fn10() {
86 boost::throw_exception( my_exception() );
87 return A();
88}
89
90void fn11( boost::fibers::promise< int > p) {
91 boost::this_fiber::sleep_for( ms(500) );
92 p.set_value(3);
93}
94
95void fn12( boost::fibers::promise< int& > p) {
96 boost::this_fiber::sleep_for( ms(500) );
97 gi = 5;
98 p.set_value( gi);
99}
100
101void fn13( boost::fibers::promise< void > p) {
b32b8144 102 boost::this_fiber::sleep_for( ms(400) );
7c673cae
FG
103 p.set_value();
104}
105
106// future
107void 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
118void 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
129void 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
140void 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
157void 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
174void 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
191void 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
219void 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
248void 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
279void 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
307void 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
328void 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
349void 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
368void 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
379void 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
392void 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
404void 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::dispatch, 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() );
b32b8144 417 status = f1.wait_for( ms(400) );
7c673cae
FG
418 BOOST_CHECK( boost::fibers::future_status::ready == status);
419
420 BOOST_CHECK( f1.valid() );
421 f1.wait();
422}
423
424void 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::dispatch, 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() );
b32b8144 437 status = f1.wait_for( ms(400) );
7c673cae
FG
438 BOOST_CHECK( boost::fibers::future_status::ready == status);
439
440 BOOST_CHECK( f1.valid() );
441 f1.wait();
442}
443
444void 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::dispatch, 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() );
b32b8144 457 status = f1.wait_for( ms(400) );
7c673cae
FG
458 BOOST_CHECK( boost::fibers::future_status::ready == status);
459
460 BOOST_CHECK( f1.valid() );
461 f1.wait();
462}
463
464void 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::dispatch, 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() );
b32b8144 477 status = f1.wait_until( Clock::now() + ms(400) );
7c673cae
FG
478 BOOST_CHECK( boost::fibers::future_status::ready == status);
479
480 BOOST_CHECK( f1.valid() );
481 f1.wait();
482}
483
484void 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::dispatch, 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() );
b32b8144 497 status = f1.wait_until( Clock::now() + ms(400) );
7c673cae
FG
498 BOOST_CHECK( boost::fibers::future_status::ready == status);
499
500 BOOST_CHECK( f1.valid() );
501 f1.wait();
502}
503
504void 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::dispatch, 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() );
b32b8144 517 status = f1.wait_until( Clock::now() + ms(400) );
7c673cae
FG
518 BOOST_CHECK( boost::fibers::future_status::ready == status);
519
520 BOOST_CHECK( f1.valid() );
521 f1.wait();
522}
523
524void test_future_wait_with_fiber_1() {
525 boost::fibers::promise< int > p1;
526 boost::fibers::fiber( boost::fibers::launch::dispatch, 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
534void test_future_wait_with_fiber_2() {
535 boost::fibers::fiber( boost::fibers::launch::dispatch, fn2).join();
536}
537
538
539boost::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}