mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 08:46:44 +08:00
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:
parent
e2b5fc36fe
commit
e6f817ca7b
@ -1 +1 @@
|
|||||||
Subproject commit 8087252a0c3c2f0baad96ddbd6554db17a846376
|
Subproject commit 6c054e98f3f53352d12b6cd46d63b6d404cc044b
|
||||||
@ -50,18 +50,22 @@ void unexpected_error(cti::exception_t);
|
|||||||
// Check that the failure was an aborted operation, as expected.
|
// Check that the failure was an aborted operation, as expected.
|
||||||
void check_aborted_operation(cti::exception_t);
|
void check_aborted_operation(cti::exception_t);
|
||||||
|
|
||||||
|
// Use a strand as executor
|
||||||
|
void using_strand();
|
||||||
|
|
||||||
int main(int, char**) {
|
int main(int, char**) {
|
||||||
daytime_service();
|
daytime_service();
|
||||||
|
|
||||||
successful_async_wait();
|
successful_async_wait();
|
||||||
cancelled_async_wait();
|
cancelled_async_wait();
|
||||||
|
|
||||||
|
using_strand();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void daytime_service() {
|
void daytime_service() {
|
||||||
using asio::ip::tcp;
|
using asio::ip::tcp;
|
||||||
|
|
||||||
asio::io_context ioc(1);
|
asio::io_context ioc(1);
|
||||||
tcp::resolver resolver(ioc);
|
tcp::resolver resolver(ioc);
|
||||||
tcp::socket socket(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.");
|
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();
|
||||||
|
}
|
||||||
|
|||||||
58
include/continuable/detail/external/asio.hpp
vendored
58
include/continuable/detail/external/asio.hpp
vendored
@ -109,31 +109,50 @@ using system_error_t = ::boost::system::system_error;
|
|||||||
# endif
|
# endif
|
||||||
#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>
|
template <typename Promise, typename Token>
|
||||||
auto promise_resolver_handler(Promise&& promise, Token&& token) noexcept {
|
class promise_resolver {
|
||||||
return [promise = std::forward<Promise>(promise),
|
public:
|
||||||
token = std::forward<Token>(token)](error_code_t e,
|
explicit promise_resolver(Promise promise, Token token)
|
||||||
auto&&... args) mutable noexcept {
|
: 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 (e) {
|
||||||
if (!token.is_ignored(e)) {
|
if (!token_.is_ignored(e)) {
|
||||||
if (token.is_cancellation(e)) {
|
if (token_.is_cancellation(e)) {
|
||||||
promise.set_canceled();
|
promise_.set_canceled();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
#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(exception_t(e.value(), e.category()));
|
promise_.set_exception(exception_t(e.value(), e.category()));
|
||||||
#endif
|
#endif
|
||||||
return;
|
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,
|
// 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>
|
template <typename Signature>
|
||||||
struct initiate_make_continuable;
|
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>
|
template <typename... Args>
|
||||||
struct initiate_make_continuable<void(error_code_t, Args...)> {
|
struct initiate_make_continuable<void(error_code_t, Args...)> {
|
||||||
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
|
#if defined(CTI_DETAIL_ASIO_HAS_EXPLICIT_RET_TYPE_INTEGRATION)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user