This commit is contained in:
Timur A. Fatkhullin 2024-09-18 16:35:13 +03:00
parent 61cf7553af
commit da4b958d6b
2 changed files with 114 additions and 25 deletions

View File

@ -52,8 +52,9 @@ concept adc_asio_stream_transport_proto_c =
template <typename T>
concept adc_asio_is_future = requires {
[]<typename AllocatorT>(std::type_identity<asio::use_future_t<AllocatorT>>) {
}(std::type_identity<std::remove_cvref_t<T>>());
[](std::type_identity<asio::use_future_t<>>) {}(std::type_identity<std::remove_cvref_t<T>>());
// []<typename AllocatorT>(std::type_identity<asio::use_future_t<AllocatorT>>) {
// }(std::type_identity<std::remove_cvref_t<T>>());
};
template <typename T>
@ -103,6 +104,63 @@ public:
std::function<void(std::error_code, RMSGT)> receive_comp_token;
};
class contx_t
{
std::function<void(std::error_code)> _errc_comp_token;
std::function<void(std::error_code, RMSGT)> _errc_msg_comp_token;
public:
contx_t() = default;
template <asio::completion_token_for<void(std::error_code)> TokenT>
contx_t(TokenT&& token)
{
_errc_comp_token = std::forward<TokenT>(token);
}
template <asio::completion_token_for<void(std::error_code, RMSGT)> TokenT>
contx_t(TokenT&& token)
{
_errc_msg_comp_token = std::forward<TokenT>(token);
}
template <asio::completion_token_for<void(std::error_code)> TokenT>
contx_t& operator=(TokenT&& token)
{
_errc_comp_token = std::forward<TokenT>(token);
return *this;
}
template <asio::completion_token_for<void(std::error_code, RMSGT)> TokenT>
contx_t& operator=(TokenT&& token)
{
_errc_msg_comp_token = std::forward<TokenT>(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 <asio::completion_token_for<void(std::error_code)> TokenT>
operator TokenT() const
{
return _errc_comp_token;
}
template <asio::completion_token_for<void(std::error_code, RMSGT)> 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 <adc_completion_token_c<void(std::error_code)> 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<TokenT, async_call_ctx_t>, "'async_call_ctx_t'-TYPE MUST NOT BE USED!");
// template <adc_completion_token_c<void(std::error_code)> 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<TokenT, async_call_ctx_t>, "'async_call_ctx_t'-TYPE MUST NOT BE USED!");
// auto timer = getDeadlineTimer(timeout);
// auto comp_token = [wrapper = traits::adc_pf_wrapper(std::forward<TokenT>(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<TokenT>) {
// std::get<0>(wrapper)(ec);
// }
// };
// if constexpr (!adc_asio_is_future<TokenT>) {
// return _socket.async_connect(endpoint, asio::use_future(std::move(comp_token)));
// } else {
// return _socket.async_connect(endpoint, std::move(comp_token));
// }
// }
template <asio::completion_token_for<void(std::error_code)> 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<TokenT>(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<CompTokenT, void(asio::error_code)>(
[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<TokenT>) {
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<TokenT>) {
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 <traits::adc_input_char_range SMSGT,
template <traits::adc_input_char_range MessageT,
adc_completion_token_c<void(std::error_code ec)> 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<TokenT, async_call_ctx_t>, "'async_call_ctx_t'-TYPE MUST NOT BE USED!");

View File

@ -22,6 +22,11 @@ int main()
});
adc::impl::AdcNetServiceASIOBase<asio::ip::tcp, adc::AdcStopSeqSessionProto<>>::contx_t s_ctx;
srv.asyncConnect(ept_c, s_ctx);
srv.asyncConnect(ept_c, asio::use_future);
ctx.run();
return 0;