Add the void(...) asio handler overload to the use_continuable initiation token

* Makes it possible to use the initiation token with dispatch/post
* Ref #44
This commit is contained in:
Denis Blank 2021-10-22 07:53:20 +02:00
parent e2b5fc36fe
commit e6f817ca7b
3 changed files with 75 additions and 15 deletions

@ -1 +1 @@
Subproject commit 8087252a0c3c2f0baad96ddbd6554db17a846376
Subproject commit 6c054e98f3f53352d12b6cd46d63b6d404cc044b

View File

@ -50,18 +50,22 @@ void unexpected_error(cti::exception_t);
// Check that the failure was an aborted operation, as expected.
void check_aborted_operation(cti::exception_t);
// Use a strand as executor
void using_strand();
int main(int, char**) {
daytime_service();
successful_async_wait();
cancelled_async_wait();
using_strand();
return 0;
}
void daytime_service() {
using asio::ip::tcp;
asio::io_context ioc(1);
tcp::resolver resolver(ioc);
tcp::socket socket(ioc);
@ -146,3 +150,27 @@ void check_aborted_operation(cti::exception_t ex) {
puts("Continuation failed due to aborted async operation, as expected.");
}
}
template <typename T>
auto through_post(T& postable) {
return [&postable](auto&& work) mutable {
asio::post(postable, std::forward<decltype(work)>(work));
};
}
void using_strand() {
asio::io_context ioc(1);
asio::io_context::strand strand(ioc);
asio::post(strand, cti::use_continuable).then([]() {
puts("Dispatched through initiation token");
});
cti::async_on(
[]() mutable {
puts("Dispatched through executor token");
},
through_post(strand));
ioc.run();
}

View File

@ -109,31 +109,50 @@ using system_error_t = ::boost::system::system_error;
# endif
#endif
// Binds `promise` to the first argument of a continuable resolver, giving it
// the signature of an ASIO handler.
template <typename Promise, typename Token>
auto promise_resolver_handler(Promise&& promise, Token&& token) noexcept {
return [promise = std::forward<Promise>(promise),
token = std::forward<Token>(token)](error_code_t e,
auto&&... args) mutable noexcept {
class promise_resolver {
public:
explicit promise_resolver(Promise promise, Token token)
: promise_(std::move(promise))
, token_(std::move(token)) {}
template <typename... T>
void operator()(T&&... args) noexcept {
promise_.set_value(std::forward<T>(args)...);
}
template <typename... T>
void operator()(error_code_t e, T&&... args) noexcept {
if (e) {
if (!token.is_ignored(e)) {
if (token.is_cancellation(e)) {
promise.set_canceled();
if (!token_.is_ignored(e)) {
if (token_.is_cancellation(e)) {
promise_.set_canceled();
return;
} else {
#if defined(CONTINUABLE_HAS_EXCEPTIONS)
promise.set_exception(
promise_.set_exception(
std::make_exception_ptr(system_error_t(std::move(e))));
#else
promise.set_exception(exception_t(e.value(), e.category()));
promise_.set_exception(exception_t(e.value(), e.category()));
#endif
return;
}
}
}
promise.set_value(std::forward<decltype(args)>(args)...);
};
promise_.set_value(std::forward<T>(args)...);
}
private:
Promise promise_;
Token token_;
};
// Binds `promise` to the first argument of a continuable resolver, giving it
// the signature of an ASIO handler.
template <typename Promise, typename Token>
auto promise_resolver_handler(Promise&& promise, Token&& token) noexcept {
return promise_resolver<std::decay_t<Promise>, std::decay_t<Token>>(
std::forward<Promise>(promise), std::forward<Token>(token));
}
// Helper struct wrapping a call to `cti::make_continuable` and, if needed,
@ -141,6 +160,19 @@ auto promise_resolver_handler(Promise&& promise, Token&& token) noexcept {
template <typename Signature>
struct initiate_make_continuable;
template <typename... Args>
struct initiate_make_continuable<void(Args...)> {
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
using erased_return_type = continuable<Args...>;
#endif
template <typename Continuation>
auto operator()(Continuation&& continuation) {
return base::attorney::create_from(std::forward<Continuation>(continuation),
identity<Args...>{}, util::ownership{});
}
};
template <typename... Args>
struct initiate_make_continuable<void(error_code_t, Args...)> {
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)