summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/fiber/test/test_future_dispatch.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/fiber/test/test_future_dispatch.cpp
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/fiber/test/test_future_dispatch.cpp')
-rw-r--r--src/boost/libs/fiber/test/test_future_dispatch.cpp569
1 files changed, 569 insertions, 0 deletions
diff --git a/src/boost/libs/fiber/test/test_future_dispatch.cpp b/src/boost/libs/fiber/test/test_future_dispatch.cpp
new file mode 100644
index 000000000..2990ec41a
--- /dev/null
+++ b/src/boost/libs/fiber/test/test_future_dispatch.cpp
@@ -0,0 +1,569 @@
+// (C) Copyright 2008-10 Anthony Williams
+// 2015 Oliver Kowalke
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <chrono>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <utility>
+
+#include <boost/test/unit_test.hpp>
+
+#include <boost/fiber/all.hpp>
+
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::high_resolution_clock Clock;
+
+int gi = 7;
+
+struct my_exception : public std::runtime_error {
+ my_exception() :
+ std::runtime_error("my_exception") {
+ }
+};
+
+struct A {
+ A() = default;
+
+ A( A const&) = delete;
+ A( A &&) = default;
+
+ A & operator=( A const&) = delete;
+ A & operator=( A &&) = default;
+
+ int value;
+};
+
+void fn1( boost::fibers::promise< int > * p, int i) {
+ boost::this_fiber::yield();
+ p->set_value( i);
+}
+
+void fn2() {
+ boost::fibers::promise< int > p;
+ boost::fibers::future< int > f( p.get_future() );
+ boost::this_fiber::yield();
+ boost::fibers::fiber( boost::fibers::launch::dispatch, fn1, & p, 7).detach();
+ boost::this_fiber::yield();
+ BOOST_CHECK( 7 == f.get() );
+}
+
+int fn3() {
+ return 3;
+}
+
+void fn4() {
+}
+
+int fn5() {
+ boost::throw_exception( my_exception() );
+ return 3;
+}
+
+void fn6() {
+ boost::throw_exception( my_exception() );
+}
+
+int & fn7() {
+ return gi;
+}
+
+int fn8( int i) {
+ return i;
+}
+
+A fn9() {
+ A a;
+ a.value = 3;
+ return a;
+}
+
+A fn10() {
+ boost::throw_exception( my_exception() );
+ return A();
+}
+
+void fn11( boost::fibers::promise< int > p) {
+ boost::this_fiber::sleep_for( ms(500) );
+ p.set_value(3);
+}
+
+void fn12( boost::fibers::promise< int& > p) {
+ boost::this_fiber::sleep_for( ms(500) );
+ gi = 5;
+ p.set_value( gi);
+}
+
+void fn13( boost::fibers::promise< void > p) {
+ boost::this_fiber::sleep_for( ms(400) );
+ p.set_value();
+}
+
+// future
+void test_future_create() {
+ // default constructed future is not valid
+ boost::fibers::future< int > f1;
+ BOOST_CHECK( ! f1.valid() );
+
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int > p2;
+ boost::fibers::future< int > f2 = p2.get_future();
+ BOOST_CHECK( f2.valid() );
+}
+
+void test_future_create_ref() {
+ // default constructed future is not valid
+ boost::fibers::future< int& > f1;
+ BOOST_CHECK( ! f1.valid() );
+
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int& > p2;
+ boost::fibers::future< int& > f2 = p2.get_future();
+ BOOST_CHECK( f2.valid() );
+}
+
+void test_future_create_void() {
+ // default constructed future is not valid
+ boost::fibers::future< void > f1;
+ BOOST_CHECK( ! f1.valid() );
+
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< void > p2;
+ boost::fibers::future< void > f2 = p2.get_future();
+ BOOST_CHECK( f2.valid() );
+}
+
+void test_future_move() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int > p1;
+ boost::fibers::future< int > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // move construction
+ boost::fibers::future< int > f2( std::move( f1) );
+ BOOST_CHECK( ! f1.valid() );
+ BOOST_CHECK( f2.valid() );
+
+ // move assignment
+ f1 = std::move( f2);
+ BOOST_CHECK( f1.valid() );
+ BOOST_CHECK( ! f2.valid() );
+}
+
+void test_future_move_ref() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int& > p1;
+ boost::fibers::future< int& > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // move construction
+ boost::fibers::future< int& > f2( std::move( f1) );
+ BOOST_CHECK( ! f1.valid() );
+ BOOST_CHECK( f2.valid() );
+
+ // move assignment
+ f1 = std::move( f2);
+ BOOST_CHECK( f1.valid() );
+ BOOST_CHECK( ! f2.valid() );
+}
+
+void test_future_move_void() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< void > p1;
+ boost::fibers::future< void > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // move construction
+ boost::fibers::future< void > f2( std::move( f1) );
+ BOOST_CHECK( ! f1.valid() );
+ BOOST_CHECK( f2.valid() );
+
+ // move assignment
+ f1 = std::move( f2);
+ BOOST_CHECK( f1.valid() );
+ BOOST_CHECK( ! f2.valid() );
+}
+
+void test_future_get() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int > p1;
+ p1.set_value( 7);
+
+ boost::fibers::future< int > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // get
+ BOOST_CHECK( ! f1.get_exception_ptr() );
+ BOOST_CHECK( 7 == f1.get() );
+ BOOST_CHECK( ! f1.valid() );
+
+ // throw broken_promise if promise is destroyed without set
+ {
+ boost::fibers::promise< int > p2;
+ f1 = p2.get_future();
+ }
+ bool thrown = false;
+ try {
+ f1.get();
+ } catch ( boost::fibers::broken_promise const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( ! f1.valid() );
+ BOOST_CHECK( thrown);
+}
+
+void test_future_get_move() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< A > p1;
+ A a; a.value = 7;
+ p1.set_value( std::move( a) );
+
+ boost::fibers::future< A > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // get
+ BOOST_CHECK( ! f1.get_exception_ptr() );
+ BOOST_CHECK( 7 == f1.get().value);
+ BOOST_CHECK( ! f1.valid() );
+
+ // throw broken_promise if promise is destroyed without set
+ {
+ boost::fibers::promise< A > p2;
+ f1 = p2.get_future();
+ }
+ bool thrown = false;
+ try {
+ f1.get();
+ } catch ( boost::fibers::broken_promise const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( ! f1.valid() );
+ BOOST_CHECK( thrown);
+}
+
+void test_future_get_ref() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int& > p1;
+ int i = 7;
+ p1.set_value( i);
+
+ boost::fibers::future< int& > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // get
+ BOOST_CHECK( ! f1.get_exception_ptr() );
+ int & j = f1.get();
+ BOOST_CHECK( &i == &j);
+ BOOST_CHECK( ! f1.valid() );
+
+ // throw broken_promise if promise is destroyed without set
+ {
+ boost::fibers::promise< int& > p2;
+ f1 = p2.get_future();
+ }
+ bool thrown = false;
+ try {
+ f1.get();
+ } catch ( boost::fibers::broken_promise const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( ! f1.valid() );
+ BOOST_CHECK( thrown);
+}
+
+
+void test_future_get_void() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< void > p1;
+ p1.set_value();
+
+ boost::fibers::future< void > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // get
+ BOOST_CHECK( ! f1.get_exception_ptr() );
+ f1.get();
+ BOOST_CHECK( ! f1.valid() );
+
+ // throw broken_promise if promise is destroyed without set
+ {
+ boost::fibers::promise< void > p2;
+ f1 = p2.get_future();
+ }
+ bool thrown = false;
+ try {
+ f1.get();
+ } catch ( boost::fibers::broken_promise const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( ! f1.valid() );
+ BOOST_CHECK( thrown);
+}
+
+void test_future_share() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int > p1;
+ int i = 7;
+ p1.set_value( i);
+
+ boost::fibers::future< int > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // share
+ boost::fibers::shared_future< int > sf1 = f1.share();
+ BOOST_CHECK( sf1.valid() );
+ BOOST_CHECK( ! f1.valid() );
+
+ // get
+ BOOST_CHECK( ! sf1.get_exception_ptr() );
+ int j = sf1.get();
+ BOOST_CHECK_EQUAL( i, j);
+ BOOST_CHECK( sf1.valid() );
+}
+
+void test_future_share_ref() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int& > p1;
+ int i = 7;
+ p1.set_value( i);
+
+ boost::fibers::future< int& > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // share
+ boost::fibers::shared_future< int& > sf1 = f1.share();
+ BOOST_CHECK( sf1.valid() );
+ BOOST_CHECK( ! f1.valid() );
+
+ // get
+ BOOST_CHECK( ! sf1.get_exception_ptr() );
+ int & j = sf1.get();
+ BOOST_CHECK( &i == &j);
+ BOOST_CHECK( sf1.valid() );
+}
+
+void test_future_share_void() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< void > p1;
+ p1.set_value();
+
+ boost::fibers::future< void > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // share
+ boost::fibers::shared_future< void > sf1 = f1.share();
+ BOOST_CHECK( sf1.valid() );
+ BOOST_CHECK( ! f1.valid() );
+
+ // get
+ BOOST_CHECK( ! sf1.get_exception_ptr() );
+ sf1.get();
+ BOOST_CHECK( sf1.valid() );
+}
+
+void test_future_wait() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int > p1;
+ boost::fibers::future< int > f1 = p1.get_future();
+
+ // wait on future
+ p1.set_value( 7);
+ f1.wait();
+ BOOST_CHECK( 7 == f1.get() );
+}
+
+void test_future_wait_ref() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int& > p1;
+ boost::fibers::future< int& > f1 = p1.get_future();
+
+ // wait on future
+ int i = 7;
+ p1.set_value( i);
+ f1.wait();
+ int & j = f1.get();
+ BOOST_CHECK( &i == &j);
+}
+
+void test_future_wait_void() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< void > p1;
+ boost::fibers::future< void > f1 = p1.get_future();
+
+ // wait on future
+ p1.set_value();
+ f1.wait();
+ f1.get();
+ BOOST_CHECK( ! f1.valid() );
+}
+
+void test_future_wait_for() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int > p1;
+ boost::fibers::future< int > f1 = p1.get_future();
+
+ boost::fibers::fiber( boost::fibers::launch::dispatch, fn11, std::move( p1) ).detach();
+
+ // wait on future
+ BOOST_CHECK( f1.valid() );
+ boost::fibers::future_status status = f1.wait_for( ms(300) );
+ BOOST_CHECK( boost::fibers::future_status::timeout == status);
+
+ BOOST_CHECK( f1.valid() );
+ status = f1.wait_for( ms(400) );
+ BOOST_CHECK( boost::fibers::future_status::ready == status);
+
+ BOOST_CHECK( f1.valid() );
+ f1.wait();
+}
+
+void test_future_wait_for_ref() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int& > p1;
+ boost::fibers::future< int& > f1 = p1.get_future();
+
+ boost::fibers::fiber( boost::fibers::launch::dispatch, fn12, std::move( p1) ).detach();
+
+ // wait on future
+ BOOST_CHECK( f1.valid() );
+ boost::fibers::future_status status = f1.wait_for( ms(300) );
+ BOOST_CHECK( boost::fibers::future_status::timeout == status);
+
+ BOOST_CHECK( f1.valid() );
+ status = f1.wait_for( ms(400) );
+ BOOST_CHECK( boost::fibers::future_status::ready == status);
+
+ BOOST_CHECK( f1.valid() );
+ f1.wait();
+}
+
+void test_future_wait_for_void() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< void > p1;
+ boost::fibers::future< void > f1 = p1.get_future();
+
+ boost::fibers::fiber( boost::fibers::launch::dispatch, fn13, std::move( p1) ).detach();
+
+ // wait on future
+ BOOST_CHECK( f1.valid() );
+ boost::fibers::future_status status = f1.wait_for( ms(300) );
+ BOOST_CHECK( boost::fibers::future_status::timeout == status);
+
+ BOOST_CHECK( f1.valid() );
+ status = f1.wait_for( ms(400) );
+ BOOST_CHECK( boost::fibers::future_status::ready == status);
+
+ BOOST_CHECK( f1.valid() );
+ f1.wait();
+}
+
+void test_future_wait_until() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int > p1;
+ boost::fibers::future< int > f1 = p1.get_future();
+
+ boost::fibers::fiber( boost::fibers::launch::dispatch, fn11, std::move( p1) ).detach();
+
+ // wait on future
+ BOOST_CHECK( f1.valid() );
+ boost::fibers::future_status status = f1.wait_until( Clock::now() + ms(300) );
+ BOOST_CHECK( boost::fibers::future_status::timeout == status);
+
+ BOOST_CHECK( f1.valid() );
+ status = f1.wait_until( Clock::now() + ms(400) );
+ BOOST_CHECK( boost::fibers::future_status::ready == status);
+
+ BOOST_CHECK( f1.valid() );
+ f1.wait();
+}
+
+void test_future_wait_until_ref() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< int& > p1;
+ boost::fibers::future< int& > f1 = p1.get_future();
+
+ boost::fibers::fiber( boost::fibers::launch::dispatch, fn12, std::move( p1) ).detach();
+
+ // wait on future
+ BOOST_CHECK( f1.valid() );
+ boost::fibers::future_status status = f1.wait_until( Clock::now() + ms(300) );
+ BOOST_CHECK( boost::fibers::future_status::timeout == status);
+
+ BOOST_CHECK( f1.valid() );
+ status = f1.wait_until( Clock::now() + ms(400) );
+ BOOST_CHECK( boost::fibers::future_status::ready == status);
+
+ BOOST_CHECK( f1.valid() );
+ f1.wait();
+}
+
+void test_future_wait_until_void() {
+ // future retrieved from promise is valid (if it is the first)
+ boost::fibers::promise< void > p1;
+ boost::fibers::future< void > f1 = p1.get_future();
+
+ boost::fibers::fiber( boost::fibers::launch::dispatch, fn13, std::move( p1) ).detach();
+
+ // wait on future
+ BOOST_CHECK( f1.valid() );
+ boost::fibers::future_status status = f1.wait_until( Clock::now() + ms(300) );
+ BOOST_CHECK( boost::fibers::future_status::timeout == status);
+
+ BOOST_CHECK( f1.valid() );
+ status = f1.wait_until( Clock::now() + ms(400) );
+ BOOST_CHECK( boost::fibers::future_status::ready == status);
+
+ BOOST_CHECK( f1.valid() );
+ f1.wait();
+}
+
+void test_future_wait_with_fiber_1() {
+ boost::fibers::promise< int > p1;
+ boost::fibers::fiber( boost::fibers::launch::dispatch, fn1, & p1, 7).detach();
+
+ boost::fibers::future< int > f1 = p1.get_future();
+
+ // wait on future
+ BOOST_CHECK( 7 == f1.get() );
+}
+
+void test_future_wait_with_fiber_2() {
+ boost::fibers::fiber( boost::fibers::launch::dispatch, fn2).join();
+}
+
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) {
+ boost::unit_test_framework::test_suite* test =
+ BOOST_TEST_SUITE("Boost.Fiber: future test suite");
+
+ test->add(BOOST_TEST_CASE(test_future_create));
+ test->add(BOOST_TEST_CASE(test_future_create_ref));
+ test->add(BOOST_TEST_CASE(test_future_create_void));
+ test->add(BOOST_TEST_CASE(test_future_move));
+ test->add(BOOST_TEST_CASE(test_future_move_ref));
+ test->add(BOOST_TEST_CASE(test_future_move_void));
+ test->add(BOOST_TEST_CASE(test_future_get));
+ test->add(BOOST_TEST_CASE(test_future_get_move));
+ test->add(BOOST_TEST_CASE(test_future_get_ref));
+ test->add(BOOST_TEST_CASE(test_future_get_void));
+ test->add(BOOST_TEST_CASE(test_future_share));
+ test->add(BOOST_TEST_CASE(test_future_share_ref));
+ test->add(BOOST_TEST_CASE(test_future_share_void));
+ test->add(BOOST_TEST_CASE(test_future_wait));
+ test->add(BOOST_TEST_CASE(test_future_wait_ref));
+ test->add(BOOST_TEST_CASE(test_future_wait_void));
+ test->add(BOOST_TEST_CASE(test_future_wait_for));
+ test->add(BOOST_TEST_CASE(test_future_wait_for_ref));
+ test->add(BOOST_TEST_CASE(test_future_wait_for_void));
+ test->add(BOOST_TEST_CASE(test_future_wait_until));
+ test->add(BOOST_TEST_CASE(test_future_wait_until_ref));
+ test->add(BOOST_TEST_CASE(test_future_wait_until_void));
+ test->add(BOOST_TEST_CASE(test_future_wait_with_fiber_1));
+ test->add(BOOST_TEST_CASE(test_future_wait_with_fiber_2));
+
+ return test;
+}