From ccf7eecc29c257e1a819c96a9cc1d92d68ab6acd Mon Sep 17 00:00:00 2001 From: wyc <1104749580@qq.com> Date: Mon, 29 Jun 2026 08:50:10 +0800 Subject: [PATCH] =?UTF-8?q?concurrencpp=20=E6=8D=A2=E6=88=90asio=E5=8D=8F?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Base/Coro_Result.h | 84 ++++++++++----- Core/Serial/Serial_Coro.h | 73 +++++++------ Core/socket/Socket_Coro.h | 210 ++++++++++---------------------------- main.cmake | 3 - 4 files changed, 152 insertions(+), 218 deletions(-) diff --git a/Core/Base/Coro_Result.h b/Core/Base/Coro_Result.h index 4ae803d..5541003 100644 --- a/Core/Base/Coro_Result.h +++ b/Core/Base/Coro_Result.h @@ -1,6 +1,11 @@ #pragma once -#include +#include +#include +#include +#include +#include #include +#include #include #include #include @@ -8,39 +13,72 @@ namespace Psc::coro { template class Result_Completion { public: - explicit Result_Completion( - std::shared_ptr> promise) - : promise_(std::move(promise)) {} - void operator()(T value) { promise_->set_result(std::move(value)); } + using Complete = std::function; + 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> promise_; + Complete complete_; }; template <> class Result_Completion { public: - explicit Result_Completion( - std::shared_ptr> promise) - : promise_(std::move(promise)) {} - void operator()() { promise_->set_result(); } + using Complete = std::function; + 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> promise_; + Complete complete_; }; template -[[nodiscard]] concurrencpp::result callback_result(Starter &&starter) { - auto promise = std::make_shared>(); - auto result = promise->get_result(); - try { - std::forward(starter)(Result_Completion{promise}); - } catch (...) { - promise->set_exception(std::current_exception()); +[[nodiscard]] asio::awaitable 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( + [starter = std::forward(starter), executor](auto handler) mutable { + auto handler_ptr = std::make_shared>(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{std::move(complete)}); + } catch (...) { + complete(std::current_exception(), T{}); + } + }, + token); + if (exception) { + std::rethrow_exception(exception); } - return result; + co_return std::move(value); +} +template +[[nodiscard]] asio::awaitable 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( + [starter = std::forward(starter), executor](auto handler) mutable { + auto handler_ptr = std::make_shared>(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{std::move(complete)}); + } catch (...) { + complete(std::current_exception()); + } + }, + token); + if (exception) { + std::rethrow_exception(exception); + } + co_return; } } // namespace Psc::coro diff --git a/Core/Serial/Serial_Coro.h b/Core/Serial/Serial_Coro.h index 14833b4..f6d21b4 100644 --- a/Core/Serial/Serial_Coro.h +++ b/Core/Serial/Serial_Coro.h @@ -1,11 +1,11 @@ #pragma once #include "Serial.h" +#include #include #include #include #include -#include #include #include @@ -50,53 +50,28 @@ public: io_context_.restart(); } - [[nodiscard]] concurrencpp::result tick_coro() { - io_context_.poll(); + [[nodiscard]] asio::awaitable tick_coro() { + tick(); co_return; } - [[nodiscard]] concurrencpp::result + [[nodiscard]] asio::awaitable read_coro(std::size_t max_size = 16 * 1024) { - co_await tick_coro(); - if (!port_ || !port_->is_open()) { - co_return ""; - } - - auto available = serial::get_available_bytes(port_->native_handle()); - if (available <= 0) { - co_return ""; - } - - auto data = serial::read_all(port_->native_handle()); - if (data.size() > max_size) { - data.resize(max_size); - } - co_return data; + co_return read_impl(max_size); } - [[nodiscard]] concurrencpp::result write_coro(std::string data) { - co_await tick_coro(); - if (!port_ || !port_->is_open() || data.empty()) { - co_return 0; - } - - asio::error_code ec; - auto size = asio::write(*port_, asio::buffer(data), ec); - if (ec) { - co_return 0; - } - - co_return size; + [[nodiscard]] asio::awaitable write_coro(std::string data) { + co_return write_impl(data); } std::string read(int64_t size = -1) { auto max_size = size > 0 ? static_cast(size) : static_cast(16 * 1024); - return (read_coro(max_size)).get(); + return read_impl(max_size); } int64_t write(const std::string &data) { - return static_cast(write_coro(data).get()); + return static_cast(write_impl(data)); } int get_available_bytes() { @@ -107,6 +82,36 @@ public: } private: + void tick() { + io_context_.poll(); + } + + std::string read_impl(std::size_t max_size) { + tick(); + if (!port_ || !port_->is_open()) { + return ""; + } + auto available = serial::get_available_bytes(port_->native_handle()); + if (available <= 0) { + return ""; + } + auto data = serial::read_all(port_->native_handle()); + if (data.size() > max_size) { + data.resize(max_size); + } + return data; + } + + std::size_t write_impl(const std::string &data) { + tick(); + if (!port_ || !port_->is_open() || data.empty()) { + return 0; + } + asio::error_code ec; + auto size = asio::write(*port_, asio::buffer(data), ec); + return ec ? 0 : size; + } + static std::string normalize_port_name(std::string port_name) { #ifdef _WIN32 if (port_name.rfind("\\\\.\\", 0) != 0) { diff --git a/Core/socket/Socket_Coro.h b/Core/socket/Socket_Coro.h index 2ea3e24..31e4a95 100644 --- a/Core/socket/Socket_Coro.h +++ b/Core/socket/Socket_Coro.h @@ -1,15 +1,14 @@ #pragma once #include "ASIO_Utils.h" -#include "Core/Base/Coro_Result.h" #include "TCP_Client.h" #include "TCP_Server.h" #include "UDP_Client.h" #include "UDP_Server.h" -#include - #include +#include +#include #include #include #include @@ -22,27 +21,27 @@ namespace Psc::asio_socket { class TCP_Client_Coro : public TCP_Client { public: - [[nodiscard]] concurrencpp::result connect_coro() { + [[nodiscard]] asio::awaitable connect_coro() { auto started = start_connect(); tick(); co_return started; } - [[nodiscard]] concurrencpp::result tick_coro() { + [[nodiscard]] asio::awaitable tick_coro() { tick(); co_return; } - [[nodiscard]] concurrencpp::result read_coro() { + [[nodiscard]] asio::awaitable read_coro() { co_return read(); } - [[nodiscard]] concurrencpp::result send_coro(std::string data) { + [[nodiscard]] asio::awaitable send_coro(std::string data) { send(data); co_return; } - [[nodiscard]] concurrencpp::result close_coro() { + [[nodiscard]] asio::awaitable close_coro() { close(); co_return; } @@ -50,42 +49,42 @@ public: class TCP_Server_Coro : public TCP_Server { public: - [[nodiscard]] concurrencpp::result listen_coro(std::string ip, + [[nodiscard]] asio::awaitable listen_coro(std::string ip, std::uint32_t port) { co_return listen(std::move(ip), port); } - [[nodiscard]] concurrencpp::result listen_coro(Sockaddr_In address) { + [[nodiscard]] asio::awaitable listen_coro(Sockaddr_In address) { co_return listen(address); } - [[nodiscard]] concurrencpp::result tick_coro() { + [[nodiscard]] asio::awaitable tick_coro() { tick(); co_return; } - [[nodiscard]] concurrencpp::result flush_clients_coro() { + [[nodiscard]] asio::awaitable flush_clients_coro() { flush_clients(); co_return; } - [[nodiscard]] concurrencpp::result + [[nodiscard]] asio::awaitable write_to_all_clients_coro(std::string data) { write_to_all_clients(data); co_return; } - [[nodiscard]] concurrencpp::result> + [[nodiscard]] asio::awaitable> read_from_all_clients_coro() { co_return read_from_all_clients(); } - [[nodiscard]] concurrencpp::result> + [[nodiscard]] asio::awaitable> accept_coro() const { co_return accept(); } - [[nodiscard]] concurrencpp::result close_coro() { + [[nodiscard]] asio::awaitable close_coro() { close(); co_return; } @@ -93,25 +92,25 @@ public: class UDP_Client_Coro : public UDP_Client { public: - [[nodiscard]] concurrencpp::result connect_coro() { + [[nodiscard]] asio::awaitable connect_coro() { co_return connect(); } - [[nodiscard]] concurrencpp::result read_coro() { + [[nodiscard]] asio::awaitable read_coro() { co_return read(); } - [[nodiscard]] concurrencpp::result tick_coro() { + [[nodiscard]] asio::awaitable tick_coro() { tick(); co_return; } - [[nodiscard]] concurrencpp::result send_coro(std::string data) { + [[nodiscard]] asio::awaitable send_coro(std::string data) { send(data); co_return; } - [[nodiscard]] concurrencpp::result close_coro() { + [[nodiscard]] asio::awaitable close_coro() { close(); co_return; } @@ -119,36 +118,36 @@ public: class UDP_Server_Coro : public UDP_Server { public: - [[nodiscard]] concurrencpp::result bind_coro() { co_return bind(); } + [[nodiscard]] asio::awaitable bind_coro() { co_return bind(); } - [[nodiscard]] concurrencpp::result tick_coro() { + [[nodiscard]] asio::awaitable tick_coro() { tick(); co_return; } - [[nodiscard]] concurrencpp::result> read_coro() { + [[nodiscard]] asio::awaitable> read_coro() { co_return read(); } - [[nodiscard]] concurrencpp::result + [[nodiscard]] asio::awaitable reply_last_peer_coro(std::string data) { reply_last_peer(data); co_return; } - [[nodiscard]] concurrencpp::result + [[nodiscard]] asio::awaitable send_to_coro(std::string ip, uint16_t port, std::string data) { send_to(ip, port, data); co_return; } - [[nodiscard]] concurrencpp::result + [[nodiscard]] asio::awaitable write_to_all_clients_coro(std::string msg) { write_to_all_clients(msg); co_return; } - [[nodiscard]] concurrencpp::result close_coro() { + [[nodiscard]] asio::awaitable close_coro() { close(); co_return; } @@ -173,171 +172,66 @@ inline void throw_if_error(const asio::error_code &ec) { } } -inline concurrencpp::result< +inline asio::awaitable< std::shared_ptr> tcp_resolve(asio::ip::tcp::resolver &resolver, std::string host, std::uint16_t port) { - auto endpoints = co_await Psc::coro::callback_result< - std::shared_ptr>( - [&resolver, host = std::move(host), port](auto done) mutable { - resolver.async_resolve( - host, std::to_string(port), - [done = std::move(done)]( - const asio::error_code &ec, - asio::ip::tcp::resolver::results_type endpoints) mutable { - if (ec) { - done.set_exception( - std::make_exception_ptr(std::system_error(ec))); - return; - } - done(std::make_shared( - std::move(endpoints))); - }); - }); - co_return endpoints; + auto endpoints = + co_await resolver.async_resolve(host, std::to_string(port), asio::use_awaitable); + co_return std::make_shared(std::move(endpoints)); } -inline concurrencpp::result +inline asio::awaitable tcp_connect(asio::ip::tcp::socket &socket, const asio::ip::tcp::resolver::results_type &endpoints) { - struct Result { - asio::error_code ec; - asio::ip::tcp::endpoint endpoint; - }; - - auto result = co_await Psc::coro::callback_result( - [&socket, &endpoints](auto done) mutable { - asio::async_connect( - socket, endpoints, - [done = std::move(done)]( - const asio::error_code &ec, - const asio::ip::tcp::endpoint &endpoint) mutable { - done(Result{ec, endpoint}); - }); - }); - - throw_if_error(result.ec); - co_return result.endpoint; + co_return co_await asio::async_connect(socket, endpoints, asio::use_awaitable); } -inline concurrencpp::result +inline asio::awaitable tcp_connect(asio::ip::tcp::socket &socket, asio::ip::tcp::resolver &resolver, std::string host, std::uint16_t port) { auto endpoints = co_await tcp_resolve(resolver, std::move(host), port); co_return co_await tcp_connect(socket, *endpoints); } -inline concurrencpp::result> +inline asio::awaitable> tcp_accept(asio::ip::tcp::acceptor &acceptor) { auto socket = std::make_shared(acceptor.get_executor()); - - auto ec = co_await Psc::coro::callback_result( - [&acceptor, socket](auto done) mutable { - acceptor.async_accept( - *socket, [done = std::move(done)]( - const asio::error_code &ec) mutable { done(ec); }); - }); - - throw_if_error(ec); + co_await acceptor.async_accept(*socket, asio::use_awaitable); co_return socket; } -inline concurrencpp::result +inline asio::awaitable tcp_read_some(asio::ip::tcp::socket &socket, std::size_t max_size = 16 * 1024) { - struct Result { - asio::error_code ec; - std::size_t size{}; - }; - - auto buffer = std::make_shared>(max_size); - auto result = co_await Psc::coro::callback_result( - [&socket, buffer](auto done) mutable { - socket.async_read_some( - asio::buffer(*buffer), - [done = std::move(done)](const asio::error_code &ec, - std::size_t size) mutable { - done(Result{ec, size}); - }); - }); - - throw_if_error(result.ec); - buffer->resize(result.size); - co_return TCP_Read_Result{std::move(*buffer)}; + std::vector buffer(max_size); + auto size = co_await socket.async_read_some(asio::buffer(buffer), asio::use_awaitable); + buffer.resize(size); + co_return TCP_Read_Result{std::move(buffer)}; } -inline concurrencpp::result +inline asio::awaitable tcp_write(asio::ip::tcp::socket &socket, std::string data) { - struct Result { - asio::error_code ec; - std::size_t size{}; - }; - - auto buffer = std::make_shared(std::move(data)); - auto result = co_await Psc::coro::callback_result( - [&socket, buffer](auto done) mutable { - asio::async_write(socket, asio::buffer(*buffer), - [done = std::move(done)](const asio::error_code &ec, - std::size_t size) mutable { - done(Result{ec, size}); - }); - }); - - throw_if_error(result.ec); - co_return result.size; + co_return co_await asio::async_write(socket, asio::buffer(data), asio::use_awaitable); } -inline concurrencpp::result +inline asio::awaitable udp_receive_from(asio::ip::udp::socket &socket, std::size_t max_size = 16 * 1024) { - struct Result { - asio::error_code ec; - std::size_t size{}; - asio::ip::udp::endpoint remote; - }; - - auto buffer = std::make_shared>(max_size); - auto remote = std::make_shared(); - auto result = co_await Psc::coro::callback_result( - [&socket, buffer, remote](auto done) mutable { - socket.async_receive_from( - asio::buffer(*buffer), *remote, - [done = std::move(done), remote](const asio::error_code &ec, - std::size_t size) mutable { - done(Result{ec, size, *remote}); - }); - }); - - throw_if_error(result.ec); - buffer->resize(result.size); - co_return UDP_Read_Result{endpoint_to_sockaddr(result.remote), - std::move(*buffer)}; + std::vector buffer(max_size); + asio::ip::udp::endpoint remote; + auto size = co_await socket.async_receive_from(asio::buffer(buffer), remote, asio::use_awaitable); + buffer.resize(size); + co_return UDP_Read_Result{endpoint_to_sockaddr(remote), std::move(buffer)}; } -inline concurrencpp::result +inline asio::awaitable udp_send_to(asio::ip::udp::socket &socket, std::string data, asio::ip::udp::endpoint remote) { - struct Result { - asio::error_code ec; - std::size_t size{}; - }; - - auto buffer = std::make_shared(std::move(data)); - auto result = co_await Psc::coro::callback_result( - [&socket, buffer, remote = std::move(remote)](auto done) mutable { - socket.async_send_to( - asio::buffer(*buffer), remote, - [done = std::move(done)](const asio::error_code &ec, - std::size_t size) mutable { - done(Result{ec, size}); - }); - }); - - throw_if_error(result.ec); - co_return result.size; + co_return co_await socket.async_send_to(asio::buffer(data), remote, asio::use_awaitable); } -inline concurrencpp::result +inline asio::awaitable udp_send_to(asio::ip::udp::socket &socket, std::string data, const Sockaddr_In &remote) { asio::error_code ec; diff --git a/main.cmake b/main.cmake index 554e932..1ab0cba 100644 --- a/main.cmake +++ b/main.cmake @@ -195,9 +195,6 @@ if(1) endif() -find_package(concurrencpp CONFIG REQUIRED) - -target_link_libraries(Core_Static PUBLIC concurrencpp::concurrencpp) target_link_libraries(Core_Static PUBLIC boost_pfr)