concurrencpp 换成asio协程
This commit is contained in:
+61
-23
@@ -1,6 +1,11 @@
|
||||
#pragma once
|
||||
#include <concurrencpp/concurrencpp.h>
|
||||
#include <asio/as_tuple.hpp>
|
||||
#include <asio/awaitable.hpp>
|
||||
#include <asio/dispatch.hpp>
|
||||
#include <asio/this_coro.hpp>
|
||||
#include <asio/use_awaitable.hpp>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@@ -8,39 +13,72 @@
|
||||
namespace Psc::coro {
|
||||
template <typename T> class Result_Completion {
|
||||
public:
|
||||
explicit Result_Completion(
|
||||
std::shared_ptr<concurrencpp::result_promise<T>> promise)
|
||||
: promise_(std::move(promise)) {}
|
||||
void operator()(T value) { promise_->set_result(std::move(value)); }
|
||||
using Complete = std::function<void(std::exception_ptr, T)>;
|
||||
explicit Result_Completion(Complete complete) : complete_(std::move(complete)) {}
|
||||
void operator()(T value) { complete_(nullptr, std::move(value)); }
|
||||
void set_exception(std::exception_ptr exception) {
|
||||
promise_->set_exception(exception);
|
||||
complete_(exception, T{});
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<concurrencpp::result_promise<T>> promise_;
|
||||
Complete complete_;
|
||||
};
|
||||
template <> class Result_Completion<void> {
|
||||
public:
|
||||
explicit Result_Completion(
|
||||
std::shared_ptr<concurrencpp::result_promise<void>> promise)
|
||||
: promise_(std::move(promise)) {}
|
||||
void operator()() { promise_->set_result(); }
|
||||
using Complete = std::function<void(std::exception_ptr)>;
|
||||
explicit Result_Completion(Complete complete) : complete_(std::move(complete)) {}
|
||||
void operator()() { complete_(nullptr); }
|
||||
void set_exception(std::exception_ptr exception) {
|
||||
promise_->set_exception(exception);
|
||||
complete_(exception);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<concurrencpp::result_promise<void>> promise_;
|
||||
Complete complete_;
|
||||
};
|
||||
template <typename T, typename Starter>
|
||||
[[nodiscard]] concurrencpp::result<T> callback_result(Starter &&starter) {
|
||||
auto promise = std::make_shared<concurrencpp::result_promise<T>>();
|
||||
auto result = promise->get_result();
|
||||
try {
|
||||
std::forward<Starter>(starter)(Result_Completion<T>{promise});
|
||||
} catch (...) {
|
||||
promise->set_exception(std::current_exception());
|
||||
[[nodiscard]] asio::awaitable<T> callback_result(Starter &&starter) {
|
||||
auto executor = co_await asio::this_coro::executor;
|
||||
auto token = asio::as_tuple(asio::use_awaitable);
|
||||
auto [exception, value] = co_await asio::async_initiate<decltype(token), void(std::exception_ptr, T)>(
|
||||
[starter = std::forward<Starter>(starter), executor](auto handler) mutable {
|
||||
auto handler_ptr = std::make_shared<std::decay_t<decltype(handler)>>(std::move(handler));
|
||||
auto complete = [handler_ptr, executor](std::exception_ptr exception, T value) mutable {
|
||||
asio::dispatch(executor, [handler_ptr, exception, value = std::move(value)]() mutable {
|
||||
(*handler_ptr)(exception, std::move(value));
|
||||
});
|
||||
};
|
||||
try {
|
||||
starter(Result_Completion<T>{std::move(complete)});
|
||||
} catch (...) {
|
||||
complete(std::current_exception(), T{});
|
||||
}
|
||||
},
|
||||
token);
|
||||
if (exception) {
|
||||
std::rethrow_exception(exception);
|
||||
}
|
||||
return result;
|
||||
co_return std::move(value);
|
||||
}
|
||||
template <typename Starter>
|
||||
[[nodiscard]] asio::awaitable<void> callback_result(Starter &&starter) {
|
||||
auto executor = co_await asio::this_coro::executor;
|
||||
auto token = asio::as_tuple(asio::use_awaitable);
|
||||
auto [exception] = co_await asio::async_initiate<decltype(token), void(std::exception_ptr)>(
|
||||
[starter = std::forward<Starter>(starter), executor](auto handler) mutable {
|
||||
auto handler_ptr = std::make_shared<std::decay_t<decltype(handler)>>(std::move(handler));
|
||||
auto complete = [handler_ptr, executor](std::exception_ptr exception) mutable {
|
||||
asio::dispatch(executor, [handler_ptr, exception]() mutable {
|
||||
(*handler_ptr)(exception);
|
||||
});
|
||||
};
|
||||
try {
|
||||
starter(Result_Completion<void>{std::move(complete)});
|
||||
} catch (...) {
|
||||
complete(std::current_exception());
|
||||
}
|
||||
},
|
||||
token);
|
||||
if (exception) {
|
||||
std::rethrow_exception(exception);
|
||||
}
|
||||
co_return;
|
||||
}
|
||||
} // namespace Psc::coro
|
||||
|
||||
Reference in New Issue
Block a user