summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asio/src/tests/unit/experimental/promise.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asio/src/tests/unit/experimental/promise.cpp')
-rw-r--r--3rdparty/asio/src/tests/unit/experimental/promise.cpp326
1 files changed, 116 insertions, 210 deletions
diff --git a/3rdparty/asio/src/tests/unit/experimental/promise.cpp b/3rdparty/asio/src/tests/unit/experimental/promise.cpp
index 540cae2008b..67923a4c726 100644
--- a/3rdparty/asio/src/tests/unit/experimental/promise.cpp
+++ b/3rdparty/asio/src/tests/unit/experimental/promise.cpp
@@ -2,8 +2,8 @@
// promise.cpp
// ~~~~~~~~~~~
//
-// Copyright (c) 2021 Klemens D. Morgenstern
-// (klemens dot morgenstern at gmx dot net)
+// Copyright (c) 2021-2023 Klemens D. Morgenstern
+// (klemens dot morgenstern at gmx dot net)
//
// 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)
@@ -17,6 +17,11 @@
// Test that header file is self-contained.
#include "asio/experimental/promise.hpp"
+#include "asio/append.hpp"
+#include "asio/bind_cancellation_slot.hpp"
+#include "asio/compose.hpp"
+#include "asio/deferred.hpp"
+#include "asio/experimental/use_promise.hpp"
#include "asio/steady_timer.hpp"
#include "../unit_test.hpp"
@@ -25,7 +30,6 @@ namespace promise {
void promise_tester()
{
using namespace asio;
- using asio::error_code;
using namespace std::chrono;
io_context ctx;
@@ -33,16 +37,15 @@ void promise_tester()
steady_timer timer1{ctx}, timer2{ctx};
const auto started_when = steady_clock::now();
- timer1.expires_at(started_when + milliseconds(2000));
+ timer1.expires_at(started_when + milliseconds(5000));
timer2.expires_at(started_when + milliseconds(1000));
- auto p = timer1.async_wait(experimental::use_promise);
+ auto p1 = timer1.async_wait(experimental::use_promise);
steady_clock::time_point completed_when;
- error_code ec;
+ asio::error_code ec;
bool called = false;
- p.async_wait(
- [&](auto ec_)
+ p1([&](asio::error_code ec_)
{
ec = ec_;
called = true;
@@ -50,271 +53,174 @@ void promise_tester()
});
steady_clock::time_point timer2_done;
- timer2.async_wait([&](auto) {
- timer2_done = steady_clock::now();;
- p.cancel();
- });
+ timer2.async_wait(
+ [&](asio::error_code)
+ {
+ timer2_done = steady_clock::now();
+ p1.cancel();
+ });
ctx.run();
- ASIO_CHECK(timer2_done + milliseconds(1) > completed_when);
+ static_assert(
+ asio::is_async_operation<decltype(p1)>::value,
+ "promise is async_op");
+
+ ASIO_CHECK(timer2_done + milliseconds(1) > started_when);
+ ASIO_CHECK(completed_when > timer2_done);
ASIO_CHECK(called);
ASIO_CHECK(ec == error::operation_aborted);
-}
-void promise_race_tester()
-{
- using namespace asio;
- using asio::error_code;
- using namespace std::chrono;
-
- io_context ctx;
+ timer1.expires_after(milliseconds(0));
+ auto p2 = timer1.async_wait(
+ asio::append(experimental::use_promise, 123));
- steady_timer timer1{ctx}, timer2{ctx};
+ ec = asio::error::would_block;
+ called = false;
- const auto started_when = steady_clock::now();
- timer1.expires_at(started_when + milliseconds(2000));
- timer2.expires_at(started_when + milliseconds(1000));
-
- experimental::promise<void(std::variant<error_code, error_code>)> p =
- experimental::promise<>::race(
- timer1.async_wait(experimental::use_promise),
- timer2.async_wait(experimental::use_promise));
-
- auto called = false;
- error_code ec;
- steady_clock::time_point completed_when;
- p.async_wait(
- [&](auto v)
+ p2([&](asio::error_code ec_, int i)
{
- ASIO_CHECK(v.index() == 1);
- ec = get<1>(v);
+ ASIO_CHECK(i == 123);
+ ec = ec_;
called = true;
- completed_when = steady_clock::now();
});
+ ASIO_CHECK(ec == asio::error::would_block);
+ ASIO_CHECK(!called);
+
+ ctx.restart();
ctx.run();
- ASIO_CHECK(started_when + milliseconds(1000) <= completed_when);
- ASIO_CHECK(started_when + milliseconds(1500) > completed_when);
- ASIO_CHECK(called);
+ static_assert(
+ asio::is_async_operation<decltype(p2)>::value,
+ "promise is async_op");
+
ASIO_CHECK(!ec);
+ ASIO_CHECK(called);
}
-void promise_all_tester()
+void promise_slot_tester()
{
using namespace asio;
- using asio::error_code;
using namespace std::chrono;
io_context ctx;
- steady_timer timer1{ctx},
- timer2{ctx};
+ steady_timer timer1{ctx}, timer2{ctx};
const auto started_when = steady_clock::now();
- timer1.expires_at(started_when + milliseconds(2000));
+ timer1.expires_at(started_when + milliseconds(2500));
timer2.expires_at(started_when + milliseconds(1000));
+ auto p = timer1.async_wait(experimental::use_promise);
- experimental::promise<void(error_code, error_code)> p =
- experimental::promise<>::all(
- timer1.async_wait(experimental::use_promise),
- timer2.async_wait(experimental::use_promise));
-
- bool called = false;
steady_clock::time_point completed_when;
+ asio::error_code ec;
+ bool called = false;
- p.async_wait(
- [&](auto ec1, auto ec2)
- {
- ASIO_CHECK(!ec1);
- ASIO_CHECK(!ec2);
- called = true;
- completed_when = steady_clock::now();
- });
-
- ctx.run();
-
- ASIO_CHECK(started_when + milliseconds(2000) <= completed_when);
- ASIO_CHECK(started_when + milliseconds(2500) > completed_when);
- ASIO_CHECK(called);
-}
-
-void promise_race_ranged_tester()
-{
- using namespace asio;
- using asio::error_code;
- using namespace std::chrono;
-
- io_context ctx;
-
- steady_timer timer1{ctx}, timer2{ctx};
+ asio::cancellation_signal sig;
- const auto started_when = steady_clock::now();
- timer1.expires_at(started_when + milliseconds(2000));
- timer2.expires_at(started_when + milliseconds(1000));
+ p(asio::bind_cancellation_slot(
+ sig.slot(),
+ [&](asio::error_code ec_)
+ {
+ ec = ec_;
+ called = true;
+ completed_when = steady_clock::now();
+ }));
- // promise<
- // std::variant<
- // tuple<error_code, std::size_t>,
- // tuple<error_code, std::size_t>>>
- experimental::promise<void(std::size_t, error_code)> p =
- experimental::promise<>::race(
- std::array{
- timer1.async_wait(experimental::use_promise),
- timer2.async_wait(experimental::use_promise)
- });
-
- auto called = false;
- auto completed_when = steady_clock::time_point();
-
- p.async_wait([&](auto idx, auto ec )
+ steady_clock::time_point timer2_done;
+ timer2.async_wait(
+ [&](asio::error_code)
{
- ASIO_CHECK(idx == 1);
- called = true;
- completed_when = steady_clock::now();
- ASIO_CHECK(!ec);
+ timer2_done = steady_clock::now();
+ sig.emit(asio::cancellation_type::all);
});
- std::array<experimental::promise<void()>, 0u> arr;
-
- experimental::promise<>::race(
- ctx.get_executor(), std::move(arr)
- ).async_wait(
- [](std::size_t idx) {ASIO_CHECK(idx == std::size_t(-1));}
- );
-
ctx.run();
- ASIO_CHECK(started_when + milliseconds(1000) <= completed_when);
- ASIO_CHECK(started_when + milliseconds(1500) > completed_when);
- ASIO_CHECK(called);
-
- std::exception_ptr ex;
-
- try
- {
- experimental::promise<>::race(std::move(arr));
- }
- catch (...)
- {
- ex = std::current_exception();
- }
+ static_assert(
+ asio::is_async_operation<decltype(p)>::value,
+ "promise is async_op");
- ASIO_CHECK(ex);
+ ASIO_CHECK(timer2_done + milliseconds(1) > started_when);
+ ASIO_CHECK(completed_when > timer2_done);
+ ASIO_CHECK(called);
+ ASIO_CHECK(ec == error::operation_aborted);
}
-void promise_all_ranged_tester()
+void early_completion()
{
using namespace asio;
- using asio::error_code;
using namespace std::chrono;
io_context ctx;
+ auto p = asio::post(ctx, asio::experimental::use_promise);
+ ctx.run();
- steady_timer timer1{ctx}, timer2{ctx};
-
- const auto started_when = steady_clock::now();
- timer1.expires_at(started_when + milliseconds(2000));
- timer2.expires_at(started_when + milliseconds(1000));
-
- // promise<
- // std::variant<
- // tuple<error_code, std::size_t>,
- // tuple<error_code, std::size_t>>>
- experimental::promise<void(std::vector<error_code>)> p =
- experimental::promise<>::all(
- std::array{
- timer1.async_wait(experimental::use_promise),
- timer2.async_wait(experimental::use_promise)
- });
-
- auto called = false;
- auto completed_when = steady_clock::time_point();
-
- p.async_wait(
- [&](auto v){
- ASIO_CHECK(v.size() == 2u);
- completed_when = steady_clock::now();
- ASIO_CHECK(!v[0]);
- ASIO_CHECK(!v[1]);
- called = true;
- });
-
- std::array<experimental::promise<void()>, 0u> arr;
- experimental::promise<>::all(
- ctx.get_executor(), std::move(arr)
- ).async_wait(
- [](auto v) {ASIO_CHECK(v.size() == 0);}
- );
+ ASIO_CHECK(p.completed());
+ bool completed = false;
+ p([&]{completed = true;});
+ ASIO_CHECK(!completed);
+ ctx.restart();
ctx.run();
+ ASIO_CHECK(completed);
+}
- ASIO_CHECK(started_when + milliseconds(2000) <= completed_when);
- ASIO_CHECK(started_when + milliseconds(2500) > completed_when);
- ASIO_CHECK(called == true);
-
- std::exception_ptr ex;
- try
+struct test_cancel_impl_op
+{
+ asio::steady_timer & tim;
+ asio::error_code &ec;
+ template<typename Self>
+ void operator()(Self& self)
{
- experimental::promise<>::all(std::move(arr));
+ tim.async_wait(std::forward<Self>(self));
}
- catch (...)
+
+ template<typename Self>
+ void operator()(Self& self, asio::error_code ec_)
{
- ex = std::current_exception();
+ ec = ec_;
+ self.complete(ec_);
}
-
- ASIO_CHECK(ex);
+};
+
+template <typename CompletionToken>
+ASIO_INITFN_AUTO_RESULT_TYPE(
+ CompletionToken, void(asio::error_code))
+test_cancel_impl(asio::steady_timer & tim,
+ asio::error_code &ec,
+ CompletionToken&& token)
+{
+ return asio::async_compose<CompletionToken, void(asio::error_code)>(
+ test_cancel_impl_op{tim, ec}, token, tim);
}
-void promise_cancel_tester()
+void test_cancel()
{
- using namespace asio;
- using asio::error_code;
- using namespace std::chrono;
-
- io_context ctx;
-
- steady_timer timer1{ctx}, timer2{ctx};
+ asio::io_context ctx;
+ asio::steady_timer tim{ctx, std::chrono::seconds(10)};
+ asio::error_code ec;
- const auto started_when = steady_clock::now();
- timer1.expires_at(started_when + milliseconds(2000));
- timer2.expires_at(started_when + milliseconds(1000));
-
- // promise<
- // std::variant<
- // tuple<error_code, std::size_t>,
- // tuple<error_code, std::size_t>>>
- experimental::promise<void(error_code, error_code)> p =
- experimental::promise<>::all(
- timer1.async_wait(experimental::use_promise),
- timer2.async_wait(experimental::use_promise));
-
- bool called = false;
- p.async_wait(
- [&](auto ec1, auto ec2)
- {
- called = true;
- ASIO_CHECK(ec1 == error::operation_aborted);
- ASIO_CHECK(ec2 == error::operation_aborted);
- });
-
- post(ctx, [&]{p.cancel();});
+ {
+ auto p = test_cancel_impl(
+ tim, ec, asio::experimental::use_promise);
+ }
ctx.run();
- ASIO_CHECK(called);
+ ASIO_CHECK_MESSAGE(
+ ec == asio::error::operation_aborted,
+ ec.message());
}
} // namespace promise
ASIO_TEST_SUITE
(
- "promise",
- ASIO_TEST_CASE(promise::promise_tester)
- ASIO_TEST_CASE(promise::promise_race_tester)
- ASIO_TEST_CASE(promise::promise_all_tester)
- ASIO_TEST_CASE(promise::promise_race_ranged_tester)
- ASIO_TEST_CASE(promise::promise_all_ranged_tester)
- ASIO_TEST_CASE(promise::promise_cancel_tester)
+ "promise",
+ ASIO_TEST_CASE(promise::promise_tester)
+ ASIO_TEST_CASE(promise::promise_slot_tester)
+ ASIO_TEST_CASE(promise::early_completion)
+ ASIO_TEST_CASE(promise::test_cancel)
)