mirror of
https://github.com/Naios/continuable.git
synced 2025-12-07 01:06:44 +08:00
Remap asio::error::basic_errors::operation_aborted to a default constructed exception_t
* Add a successful wait on the asio async timer * Closes #27 * Closes #28
This commit is contained in:
parent
564d134c75
commit
ca26bbbc87
@ -36,8 +36,12 @@
|
|||||||
// Queries the NIST daytime service and prints the current date and time
|
// Queries the NIST daytime service and prints the current date and time
|
||||||
void daytime_service();
|
void daytime_service();
|
||||||
|
|
||||||
|
// Checks that a timer async_wait returns successfully
|
||||||
|
void successful_async_wait();
|
||||||
|
|
||||||
// Checks that a cancelled timer async_wait fails with
|
// Checks that a cancelled timer async_wait fails with
|
||||||
// `asio::error::operation_aborted`
|
// `asio::error::operation_aborted` and is converted to a default constructed
|
||||||
|
// cti::exception_t.
|
||||||
void cancelled_async_wait();
|
void cancelled_async_wait();
|
||||||
|
|
||||||
// Indicates fatal error due to an unexpected failure in the continuation chain.
|
// Indicates fatal error due to an unexpected failure in the continuation chain.
|
||||||
@ -48,6 +52,8 @@ void check_aborted_operation(cti::exception_t);
|
|||||||
|
|
||||||
int main(int, char**) {
|
int main(int, char**) {
|
||||||
daytime_service();
|
daytime_service();
|
||||||
|
|
||||||
|
successful_async_wait();
|
||||||
cancelled_async_wait();
|
cancelled_async_wait();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -69,7 +75,25 @@ void daytime_service() {
|
|||||||
return asio::async_read_until(socket, asio::dynamic_buffer(buf), '\n',
|
return asio::async_read_until(socket, asio::dynamic_buffer(buf), '\n',
|
||||||
cti::use_continuable);
|
cti::use_continuable);
|
||||||
})
|
})
|
||||||
.then([&buf](std::size_t) { puts(buf.data()); })
|
.then([&buf](std::size_t) {
|
||||||
|
puts("Continuation successfully got a daytime response:");
|
||||||
|
puts(buf.c_str());
|
||||||
|
})
|
||||||
|
.fail(&unexpected_error);
|
||||||
|
|
||||||
|
ioc.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void successful_async_wait() {
|
||||||
|
asio::io_context ioc(1);
|
||||||
|
asio::steady_timer t(ioc);
|
||||||
|
|
||||||
|
t.expires_after(std::chrono::seconds(1));
|
||||||
|
|
||||||
|
t.async_wait(cti::use_continuable)
|
||||||
|
.then([] {
|
||||||
|
puts("Continuation succeeded after 1s as expected!");
|
||||||
|
})
|
||||||
.fail(&unexpected_error);
|
.fail(&unexpected_error);
|
||||||
|
|
||||||
ioc.run();
|
ioc.run();
|
||||||
@ -93,37 +117,32 @@ void cancelled_async_wait() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void unexpected_error(cti::exception_t e) {
|
void unexpected_error(cti::exception_t e) {
|
||||||
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
if (!bool(e)) {
|
||||||
std::rethrow_exception(e);
|
puts("Continuation failed with unexpected cancellation!");
|
||||||
#else
|
|
||||||
puts("Continuation failed with unexpected error");
|
|
||||||
puts(e.message().data());
|
|
||||||
std::terminate();
|
std::terminate();
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_aborted_operation(cti::exception_t ex) {
|
|
||||||
auto is_expected_error = [](auto err_val) {
|
|
||||||
if (err_val == asio::error_code(asio::error::operation_aborted)) {
|
|
||||||
puts("Continuation failed due to aborted async operation, as expected.");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
try {
|
try {
|
||||||
std::rethrow_exception(ex);
|
std::rethrow_exception(e);
|
||||||
} catch (asio::system_error const& err) {
|
} catch (std::exception const& ex) {
|
||||||
if (is_expected_error(err.code())) {
|
puts("Continuation failed with unexpected exception");
|
||||||
return;
|
puts(ex.what());
|
||||||
}
|
} catch (...) {
|
||||||
|
// Rethrow the exception to the asynchronous unhandled exception handler
|
||||||
|
std::rethrow_exception(std::current_exception());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (is_expected_error(ex)) {
|
puts("Continuation failed with unexpected error");
|
||||||
return;
|
puts(e.message().data());
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
std::terminate();
|
||||||
unexpected_error(ex);
|
}
|
||||||
|
|
||||||
|
void check_aborted_operation(cti::exception_t ex) {
|
||||||
|
if (bool(ex)) {
|
||||||
|
unexpected_error(ex);
|
||||||
|
} else {
|
||||||
|
puts("Continuation failed due to aborted async operation, as expected.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
include/continuable/detail/external/asio.hpp
vendored
19
include/continuable/detail/external/asio.hpp
vendored
@ -30,10 +30,14 @@
|
|||||||
#ifndef CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED
|
#ifndef CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED
|
||||||
#define CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED
|
#define CONTINUABLE_DETAIL_ASIO_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <continuable/continuable-base.hpp>
|
||||||
|
#include <continuable/detail/core/base.hpp>
|
||||||
#include <continuable/detail/features.hpp>
|
#include <continuable/detail/features.hpp>
|
||||||
|
|
||||||
#if defined(ASIO_STANDALONE)
|
#if defined(ASIO_STANDALONE)
|
||||||
#include <asio/async_result.hpp>
|
#include <asio/async_result.hpp>
|
||||||
|
#include <asio/error.hpp>
|
||||||
#include <asio/error_code.hpp>
|
#include <asio/error_code.hpp>
|
||||||
#include <asio/version.hpp>
|
#include <asio/version.hpp>
|
||||||
|
|
||||||
@ -51,6 +55,7 @@
|
|||||||
#define CTI_DETAIL_ASIO_NAMESPACE_END }
|
#define CTI_DETAIL_ASIO_NAMESPACE_END }
|
||||||
#else
|
#else
|
||||||
#include <boost/asio/async_result.hpp>
|
#include <boost/asio/async_result.hpp>
|
||||||
|
#include <boost/asio/error.hpp>
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
@ -79,10 +84,6 @@
|
|||||||
"integrated manually with `cti::promisify`."
|
"integrated manually with `cti::promisify`."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <continuable/detail/core/base.hpp>
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#endif
|
#endif
|
||||||
@ -93,12 +94,14 @@ namespace asio {
|
|||||||
|
|
||||||
#if defined(ASIO_STANDALONE)
|
#if defined(ASIO_STANDALONE)
|
||||||
using error_code_t = ::asio::error_code;
|
using error_code_t = ::asio::error_code;
|
||||||
|
using basic_errors_t = ::asio::error::basic_errors;
|
||||||
|
|
||||||
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
using system_error_t = ::asio::system_error;
|
using system_error_t = ::asio::system_error;
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
using error_code_t = ::boost::system::error_code;
|
using error_code_t = ::boost::system::error_code;
|
||||||
|
using basic_errors_t = ::boost::asio::error::basic_errors;
|
||||||
|
|
||||||
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
using system_error_t = ::boost::system::system_error;
|
using system_error_t = ::boost::system::system_error;
|
||||||
@ -112,12 +115,18 @@ auto promise_resolver_handler(Promise&& promise) noexcept {
|
|||||||
return [promise = std::forward<Promise>(promise)](
|
return [promise = std::forward<Promise>(promise)](
|
||||||
error_code_t e, auto&&... args) mutable noexcept {
|
error_code_t e, auto&&... args) mutable noexcept {
|
||||||
if (e) {
|
if (e) {
|
||||||
|
if (e != basic_errors_t::operation_aborted) {
|
||||||
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
|
||||||
promise.set_exception(
|
promise.set_exception(
|
||||||
std::make_exception_ptr(system_error_t(std::move(e))));
|
std::make_exception_ptr(system_error_t(std::move(e))));
|
||||||
#else
|
#else
|
||||||
promise.set_exception(cti::exception_t(e.value(), e.category()));
|
promise.set_exception(exception_t(e.value(), e.category()));
|
||||||
#endif
|
#endif
|
||||||
|
} else {
|
||||||
|
// Continuable uses a default constructed exception type to signal
|
||||||
|
// cancellation to the followed asynchronous control flow.
|
||||||
|
promise.set_exception(exception_t{});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
promise.set_value(std::forward<decltype(args)>(args)...);
|
promise.set_value(std::forward<decltype(args)>(args)...);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user