....
This commit is contained in:
parent
ad0bdf062a
commit
062c26537d
@ -109,7 +109,92 @@ concept adc_asio_special_comp_token_c =
|
||||
namespace details
|
||||
{
|
||||
|
||||
struct helper_struct_t {
|
||||
using asyncAcceptImplementation = std::nullptr_t;
|
||||
};
|
||||
|
||||
template <typename SRVT, typename DRVT = std::nullptr_t>
|
||||
class Accpt
|
||||
{
|
||||
public:
|
||||
using netservice_t = SRVT;
|
||||
|
||||
// deduce needed types
|
||||
using transport_proto_t = typename SRVT::endpoint_t::protocol_type;
|
||||
using socket_t = typename SRVT::endpoint_t::protocol_type::socket;
|
||||
using acceptor_t = std::conditional_t<std::derived_from<socket_t, asio::basic_datagram_socket<transport_proto_t>>,
|
||||
std::nullptr_t, // there is no acceptor
|
||||
typename transport_proto_t::acceptor>;
|
||||
|
||||
static constexpr std::chrono::duration DEFAULT_ACCEPT_TIMEOUT = std::chrono::seconds::max();
|
||||
|
||||
Accpt(asio::io_context& io_ctx, const netservice_t::endpoint_t& endpoint)
|
||||
: _ioContext(io_ctx), _acceptor(io_ctx, endpoint)
|
||||
{
|
||||
}
|
||||
|
||||
template <asio::completion_token_for<void(std::error_code, netservice_t)> TokenT,
|
||||
traits::adc_time_duration_c DT = decltype(DEFAULT_ACCEPT_TIMEOUT)>
|
||||
auto asyncAccept(TokenT&& token, const DT& timeout = DEFAULT_ACCEPT_TIMEOUT)
|
||||
{
|
||||
if constexpr (std::is_null_pointer_v<acceptor_t>) {
|
||||
static_assert(false, "INVALID TRANSPORT PROTOCOL TYPE!");
|
||||
}
|
||||
|
||||
auto timer = netservice_t::getDeadlineTimer(_acceptor, timeout);
|
||||
|
||||
auto srv = std::make_shared<netservice_t>(_ioContext);
|
||||
// auto srv = std::make_unique<netservice_t>(_ioContext);
|
||||
|
||||
if constexpr (std::same_as<DRVT, std::nullptr_t>) {
|
||||
return asio::async_compose<TokenT, void(std::error_code, netservice_t)>(
|
||||
_impl(this, _acceptor, std::move(timer), srv, true), token, _ioContext);
|
||||
} else {
|
||||
return asio::async_compose<TokenT, void(std::error_code, netservice_t)>(
|
||||
static_cast<DRVT*>(this)->_impl(this, _acceptor, std::move(timer), srv, true), token, _ioContext);
|
||||
}
|
||||
}
|
||||
|
||||
template <traits::adc_time_duration_c DT = decltype(DEFAULT_ACCEPT_TIMEOUT)>
|
||||
auto accept(const DT& timeout = DEFAULT_ACCEPT_TIMEOUT)
|
||||
{
|
||||
auto f = asyncAccept(asio::use_future, timeout);
|
||||
|
||||
return f.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
asio::io_context& _ioContext;
|
||||
acceptor_t _acceptor;
|
||||
|
||||
struct asyncAcceptImplementation {
|
||||
Accpt* acp;
|
||||
acceptor_t& _acceptor;
|
||||
std::shared_ptr<asio::steady_timer> timer;
|
||||
std::shared_ptr<netservice_t> srv;
|
||||
bool start;
|
||||
|
||||
void operator()(auto& self, std::error_code ec = {})
|
||||
{
|
||||
if (!ec) {
|
||||
if (start) {
|
||||
start = false;
|
||||
return _acceptor.async_accept(srv->_socket, std::move(self));
|
||||
}
|
||||
}
|
||||
|
||||
if (netservice_t::isTimeout(timer, ec)) {
|
||||
ec = std::make_error_code(std::errc::timed_out);
|
||||
} else { // an error occured in async_accept
|
||||
timer->cancel();
|
||||
}
|
||||
|
||||
self.complete(ec, std::move(*srv));
|
||||
}
|
||||
} _impl;
|
||||
};
|
||||
|
||||
/*
|
||||
// template <interfaces::adc_netservice_c SRVT>
|
||||
template <typename SRVT>
|
||||
class AdcAcceptorASIO
|
||||
@ -148,32 +233,37 @@ public:
|
||||
|
||||
auto timer = netservice_t::getDeadlineTimer(_acceptor, timeout);
|
||||
|
||||
// auto srv = std::make_shared<netservice_t>(_ioContext);
|
||||
auto srv = std::make_unique<netservice_t>(_ioContext);
|
||||
auto srv = std::make_shared<netservice_t>(_ioContext);
|
||||
// auto srv = std::make_unique<netservice_t>(_ioContext);
|
||||
|
||||
// return asio::async_compose<TokenT, void(std::error_code, netservice_t)>(
|
||||
// asyncAcceptImplementation{this, _acceptor, std::move(timer), srv, AdcAcceptorASIO::starting}, token,
|
||||
// _ioContext);
|
||||
return asio::async_compose<TokenT, void(std::error_code, netservice_t)>(
|
||||
[timer = std::move(timer), srv = std::move(srv), state = AdcAcceptorASIO::starting, this](
|
||||
// [timer = std::move(timer), srv = std::move(srv), state = AdcAcceptorASIO::native_accept, this](
|
||||
[timer = std::move(timer), srv, state = AdcAcceptorASIO::native_accept, this](
|
||||
auto& self, std::error_code ec = {}) mutable {
|
||||
if (!ec) {
|
||||
switch (state) {
|
||||
case starting:
|
||||
// _starting(srv, state, self);
|
||||
_starting(srv, state, std::move(self));
|
||||
return;
|
||||
break;
|
||||
case native_accept:
|
||||
// _native_accept(srv, state, self);
|
||||
_native_accept(srv, state, std::move(self));
|
||||
return;
|
||||
break;
|
||||
case post_accept:
|
||||
// _post_accept(srv, state, self);
|
||||
_post_accept(srv, state, std::move(self));
|
||||
return;
|
||||
break;
|
||||
case finishing:
|
||||
// _finishing(srv, state, self);
|
||||
_finishing(srv, state, std::move(self));
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -205,29 +295,33 @@ protected:
|
||||
|
||||
enum state_t { starting, native_accept, post_accept, finishing };
|
||||
|
||||
// using self_t = std::function<void(std::error_code)>;
|
||||
using self_t = std::function<void(std::error_code)>;
|
||||
// using self_t = asio::any_completion_handler<void(std::error_code)>;
|
||||
// using self_t = std::move_only_function<void(std::error_code)>;
|
||||
|
||||
|
||||
|
||||
typedef std::function<void(std::unique_ptr<netservice_t>&, state_t&, self_t)> stage_func_t;
|
||||
// typedef std::function<void(std::shared_ptr<netservice_t>&, state_t&, self_t)> stage_func_t;
|
||||
// typedef std::function<void(std::unique_ptr<netservice_t>&, state_t&, self_t)> stage_func_t;
|
||||
typedef std::function<void(std::shared_ptr<netservice_t>, state_t&, self_t)> stage_func_t;
|
||||
|
||||
stage_func_t _starting = [this](auto&, state_t& state, self_t self) mutable {
|
||||
// stage_func_t _starting = [this](auto&, state_t& state, self_t self) mutable {
|
||||
stage_func_t _starting = [this](auto, state_t& state, self_t self) mutable {
|
||||
state = native_accept;
|
||||
// asio::post(_ioContext, std::bind([](auto, auto) {}, std::move(self), std::error_code{}));
|
||||
asio::post(_ioContext, std::bind([](auto&, auto) {}, std::move(self), std::error_code{}));
|
||||
};
|
||||
|
||||
stage_func_t _native_accept = [this](auto& srv, state_t& state, self_t self) mutable {
|
||||
// stage_func_t _native_accept = [this](auto& srv, state_t& state, self_t self) mutable {
|
||||
stage_func_t _native_accept = [this](auto srv, state_t& state, self_t self) mutable {
|
||||
state = post_accept;
|
||||
_acceptor.async_accept(srv->_socket, std::move(self));
|
||||
};
|
||||
|
||||
stage_func_t _post_accept = [this](auto&, state_t& state, self_t self) mutable { state = finishing; };
|
||||
// stage_func_t _post_accept = [this](auto&, state_t& state, self_t self) mutable { state = finishing; };
|
||||
stage_func_t _post_accept = [this](auto, state_t& state, self_t self) mutable { state = finishing; };
|
||||
|
||||
stage_func_t _finishing = [](auto&, state_t&, self_t) mutable {};
|
||||
// stage_func_t _finishing = [](auto&, state_t&, self_t) mutable {};
|
||||
stage_func_t _finishing = [](auto, state_t&, self_t) mutable {};
|
||||
|
||||
/*
|
||||
struct asyncAcceptImplementation {
|
||||
AdcAcceptorASIO* acp;
|
||||
acceptor_t& _acceptor;
|
||||
@ -284,8 +378,8 @@ protected:
|
||||
self.complete(ec, std::move(*srv));
|
||||
}
|
||||
};
|
||||
*/
|
||||
};
|
||||
*/
|
||||
|
||||
} // namespace details
|
||||
|
||||
@ -296,7 +390,8 @@ template <adc_asio_transport_proto_c TRANSPORT_PROTOT,
|
||||
class AdcNetServiceASIOBase : public SESSION_PROTOT
|
||||
{
|
||||
public:
|
||||
friend details::AdcAcceptorASIO<AdcNetServiceASIOBase>;
|
||||
// friend details::AdcAcceptorASIO<AdcNetServiceASIOBase>;
|
||||
friend details::Accpt<AdcNetServiceASIOBase>;
|
||||
|
||||
// typedefs to satisfy 'adc_netservice_c' concept
|
||||
typedef std::string_view netservice_ident_t;
|
||||
@ -315,7 +410,41 @@ public:
|
||||
// typedefs from transport protocol
|
||||
using socket_t = typename TRANSPORT_PROTOT::socket;
|
||||
|
||||
typedef details::AdcAcceptorASIO<AdcNetServiceASIOBase> acceptor_t;
|
||||
// typedef details::AdcAcceptorASIO<AdcNetServiceASIOBase> acceptor_t;
|
||||
// typedef details::Accpt<AdcNetServiceASIOBase> acceptor_t;
|
||||
struct acceptor_t : details::Accpt<AdcNetServiceASIOBase, acceptor_t> {
|
||||
using base_t = details::Accpt<AdcNetServiceASIOBase, acceptor_t>;
|
||||
using base_t::base_t;
|
||||
|
||||
protected:
|
||||
using typename base_t::netservice_t;
|
||||
|
||||
struct asyncAcceptImplementation {
|
||||
acceptor_t* acp;
|
||||
typename base_t::acceptor_t& _acceptor;
|
||||
std::shared_ptr<asio::steady_timer> timer;
|
||||
std::shared_ptr<netservice_t> srv;
|
||||
bool start;
|
||||
|
||||
void operator()(auto& self, std::error_code ec = {})
|
||||
{
|
||||
if (!ec) {
|
||||
if (start) {
|
||||
start = false;
|
||||
return _acceptor.async_accept(srv->_socket, std::move(self));
|
||||
}
|
||||
}
|
||||
|
||||
if (netservice_t::isTimeout(timer, ec)) {
|
||||
ec = std::make_error_code(std::errc::timed_out);
|
||||
} else { // an error occured in async_accept
|
||||
timer->cancel();
|
||||
}
|
||||
|
||||
self.complete(ec, std::move(*srv));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
static constexpr std::chrono::duration DEFAULT_CONNECT_TIMEOUT = std::chrono::seconds(10);
|
||||
static constexpr std::chrono::duration DEFAULT_SEND_TIMEOUT = std::chrono::seconds(5);
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "../net/adc_netproto.h"
|
||||
#include "../net/asio/adc_netservice_asio.h"
|
||||
// #include "../net/asio/adc_netsrv_asio.h"
|
||||
// #include "../net/asio/adc_netservice_asio.h"
|
||||
#include "../net/asio/adc_netsrv_asio.h"
|
||||
|
||||
template <typename T>
|
||||
void receive(T srv)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user