concurrencpp 换成asio协程

This commit is contained in:
2026-06-29 08:50:10 +08:00
parent 5313ac5ae8
commit ccf7eecc29
4 changed files with 152 additions and 218 deletions
+61 -23
View File
@@ -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