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.
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// 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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user