diff --git a/net/asio/adc_netservice_asio.h b/net/asio/adc_netservice_asio.h index ab723b4..6df5a3a 100644 --- a/net/asio/adc_netservice_asio.h +++ b/net/asio/adc_netservice_asio.h @@ -52,8 +52,9 @@ concept adc_asio_stream_transport_proto_c = template concept adc_asio_is_future = requires { - [](std::type_identity>) { - }(std::type_identity>()); + [](std::type_identity>) {}(std::type_identity>()); + // [](std::type_identity>) { + // }(std::type_identity>()); }; template @@ -103,6 +104,63 @@ public: std::function receive_comp_token; }; + class contx_t + { + std::function _errc_comp_token; + std::function _errc_msg_comp_token; + + public: + contx_t() = default; + + template TokenT> + contx_t(TokenT&& token) + { + _errc_comp_token = std::forward(token); + } + + template TokenT> + contx_t(TokenT&& token) + { + _errc_msg_comp_token = std::forward(token); + } + + template TokenT> + contx_t& operator=(TokenT&& token) + { + _errc_comp_token = std::forward(token); + return *this; + } + + template TokenT> + contx_t& operator=(TokenT&& token) + { + _errc_msg_comp_token = std::forward(token); + return *this; + } + + auto operator()(std::error_code ec) + { + return _errc_comp_token(std::move(ec)); + } + + auto operator()(std::error_code ec, RMSGT msg) + { + return _errc_msg_comp_token(std::move(ec), std::move(msg)); + } + + template TokenT> + operator TokenT() const + { + return _errc_comp_token; + } + + template TokenT> + operator TokenT() const + { + return _errc_msg_comp_token; + } + }; + // to satisfy 'adc_netservice_c' concept using async_call_ctx_t = adc_asio_async_call_ctx_t; @@ -150,39 +208,65 @@ public: } - template TokenT, - traits::adc_time_duration_c TimeoutT = decltype(DEFAULT_CONNECT_TIMEOUT)> - auto asyncConnect(const endpoint_t& endpoint, TokenT&& token, const TimeoutT& timeout = DEFAULT_CONNECT_TIMEOUT) - { - static_assert(!std::is_same_v, "'async_call_ctx_t'-TYPE MUST NOT BE USED!"); + // template TokenT, + // traits::adc_time_duration_c TimeoutT = decltype(DEFAULT_CONNECT_TIMEOUT)> + // auto asyncConnect(const endpoint_t& endpoint, TokenT&& token, const TimeoutT& timeout = DEFAULT_CONNECT_TIMEOUT) + // { + // static_assert(!std::is_same_v, "'async_call_ctx_t'-TYPE MUST NOT BE USED!"); + // auto timer = getDeadlineTimer(timeout); + + // auto comp_token = [wrapper = traits::adc_pf_wrapper(std::forward(token)), + // timer = std::move(timer)](std::error_code ec) { + // if (isTimeout(timer, ec)) { + // ec = std::make_error_code(std::errc::timed_out); + // } else { + // timer->cancel(); + // } + + // if constexpr (!adc_asio_is_future) { + // std::get<0>(wrapper)(ec); + // } + // }; + + // if constexpr (!adc_asio_is_future) { + // return _socket.async_connect(endpoint, asio::use_future(std::move(comp_token))); + // } else { + // return _socket.async_connect(endpoint, std::move(comp_token)); + // } + // } + + template CompTokenT, + traits::adc_time_duration_c TimeoutT = decltype(DEFAULT_CONNECT_TIMEOUT)> + auto asyncConnect(const endpoint_t& endpoint, CompTokenT&& token, const TimeoutT& timeout = DEFAULT_CONNECT_TIMEOUT) + { auto timer = getDeadlineTimer(timeout); - auto comp_token = [wrapper = traits::adc_pf_wrapper(std::forward(token)), - timer = std::move(timer)](std::error_code ec) { - if (isTimeout(timer, ec)) { - ec = std::make_error_code(std::errc::timed_out); - } else { - timer->cancel(); - } + return asio::async_compose( + [start = true, endpoint, timer = std::move(timer), this](auto& self, asio::error_code ec = {}) mutable { + if (!ec) { + if (start) { + start = false; + return _socket.async_connect(endpoint, std::move(self)); + } + } - if constexpr (!adc_asio_is_future) { - std::get<0>(wrapper)(ec); - } - }; + if (isTimeout(timer, ec)) { + ec = std::make_error_code(std::errc::timed_out); + } else { // an error occured in async_connect + timer->cancel(); + } - if constexpr (!adc_asio_is_future) { - return _socket.async_connect(endpoint, asio::use_future(std::move(comp_token))); - } else { - return _socket.async_connect(endpoint, std::move(comp_token)); - } + self.complete(ec); + }, + token, _socket); } - template TokenT, traits::adc_time_duration_c TimeoutT = decltype(DEFAULT_SEND_TIMEOUT)> - auto asyncSend(const SMSGT& msg, TokenT&& token, const TimeoutT& timeout = DEFAULT_SEND_TIMEOUT) + auto asyncSend(const MessageT& msg, TokenT&& token, const TimeoutT& timeout = DEFAULT_SEND_TIMEOUT) { static_assert(!std::is_same_v, "'async_call_ctx_t'-TYPE MUST NOT BE USED!"); diff --git a/tests/adc_netservice_test.cpp b/tests/adc_netservice_test.cpp index a63e3ef..38f0e51 100644 --- a/tests/adc_netservice_test.cpp +++ b/tests/adc_netservice_test.cpp @@ -22,6 +22,11 @@ int main() }); + adc::impl::AdcNetServiceASIOBase>::contx_t s_ctx; + + srv.asyncConnect(ept_c, s_ctx); + srv.asyncConnect(ept_c, asio::use_future); + ctx.run(); return 0;