...
This commit is contained in:
@@ -97,6 +97,39 @@ public:
|
||||
virtual ~AdcNetSessionManager() = default;
|
||||
|
||||
protected:
|
||||
AdcNetSessionManager() = default;
|
||||
|
||||
AdcNetSessionManager(const AdcNetSessionManager&) = delete;
|
||||
AdcNetSessionManager(AdcNetSessionManager&& other)
|
||||
{
|
||||
if (this == &other) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& func : _moveCtorFunc) {
|
||||
func(this);
|
||||
}
|
||||
|
||||
_stopSessionFunc = std::move(other._stopSessionFunc);
|
||||
_moveCtorFunc = std::move(other._moveCtorFunc);
|
||||
}
|
||||
|
||||
AdcNetSessionManager& operator=(const AdcNetSessionManager&) = delete;
|
||||
AdcNetSessionManager& operator=(AdcNetSessionManager&& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
for (auto& func : _moveCtorFunc) {
|
||||
func(this);
|
||||
}
|
||||
|
||||
_stopSessionFunc = std::move(other._stopSessionFunc);
|
||||
_moveCtorFunc = std::move(other._moveCtorFunc);
|
||||
}
|
||||
|
||||
return *this;
|
||||
};
|
||||
|
||||
|
||||
template <interfaces::adc_netsession_c SessionT>
|
||||
constexpr static bool anySessionPredicate(const typename SessionT::netsession_ident_t&)
|
||||
{
|
||||
@@ -107,6 +140,7 @@ protected:
|
||||
template <interfaces::adc_netsession_c SessionT>
|
||||
static std::unordered_map<const AdcNetSessionManager*, std::set<std::weak_ptr<SessionT>>> _serverSessions;
|
||||
std::vector<std::function<bool()>> _stopSessionFunc;
|
||||
std::vector<std::function<void(const AdcNetSessionManager*)>> _moveCtorFunc;
|
||||
|
||||
template <interfaces::adc_netsession_c SessionT>
|
||||
void startSession(std::shared_ptr<SessionT>& sess_ptr)
|
||||
@@ -115,16 +149,24 @@ protected:
|
||||
if (res.second) {
|
||||
sess_ptr.start();
|
||||
|
||||
_stopSessionFunc.emplace_back([res]() {
|
||||
_stopSessionFunc.emplace_back([res, this]() {
|
||||
if (!res.first.expired()) { // session is still existing
|
||||
auto sess = res.first.lock();
|
||||
sess->stop();
|
||||
_serverSessions<SessionT>[this].erase(res.first);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// define move-function only once per SessionT!
|
||||
if (_serverSessions<SessionT>[this].size() == 1) {
|
||||
_moveCtorFunc.emplace_back([this](const AdcNetSessionManager* new_instance) {
|
||||
_serverSessions<SessionT>[new_instance] = std::move(_serverSessions<SessionT>[this]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,20 +176,31 @@ protected:
|
||||
{
|
||||
size_t N = 0;
|
||||
|
||||
std::set<std::weak_ptr<SessionT>> remove_wptr;
|
||||
|
||||
for (auto& wptr : _serverSessions<SessionT>[this]) {
|
||||
if (std::shared_ptr<SessionT> sptr = wptr.lock()) {
|
||||
if constexpr (std::same_as<PredT, decltype(anySessionPredicate<SessionT>)>) {
|
||||
sptr->stop();
|
||||
remove_wptr.emplace(wptr);
|
||||
++N;
|
||||
} else {
|
||||
if (std::forward<PredT>(comp_func)(sptr->ident())) {
|
||||
sptr->stop();
|
||||
remove_wptr.emplace(wptr);
|
||||
++N;
|
||||
}
|
||||
}
|
||||
} else { // remove already stopped sessions?!!
|
||||
remove_wptr.emplace(wptr);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& wptr : remove_wptr) {
|
||||
_serverSessions<SessionT>[this].erase(wptr);
|
||||
}
|
||||
|
||||
|
||||
return N;
|
||||
}
|
||||
|
||||
@@ -161,6 +214,7 @@ protected:
|
||||
}
|
||||
|
||||
_stopSessionFunc.clear();
|
||||
_moveCtorFunc.clear(); // there are nothing to move after stopping of all sessions
|
||||
|
||||
return N;
|
||||
}
|
||||
@@ -172,7 +226,6 @@ protected:
|
||||
|
||||
class AdcGenericNetServer : public AdcPosixGenericDaemon, public AdcNetSessionManager
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
typedef std::string server_ident_t;
|
||||
|
||||
@@ -186,8 +239,46 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AdcGenericNetServer(const AdcGenericNetServer&) = delete;
|
||||
AdcGenericNetServer(AdcGenericNetServer&& other)
|
||||
: AdcPosixGenericDaemon(std::move(other)), AdcNetSessionManager(std::move(other))
|
||||
{
|
||||
if (this == &other) {
|
||||
return;
|
||||
}
|
||||
|
||||
_serverIdent = std::move(other._serverIdent);
|
||||
_stopListenFunc = std::move(other._stopListenFunc);
|
||||
|
||||
for (auto& func : other._moveCtorFunc) {
|
||||
func(this);
|
||||
}
|
||||
|
||||
_moveCtorFunc = std::move(other._moveCtorFunc);
|
||||
}
|
||||
|
||||
virtual ~AdcGenericNetServer() = default;
|
||||
|
||||
AdcGenericNetServer& operator=(const AdcGenericNetServer&) = delete;
|
||||
AdcGenericNetServer& operator=(AdcGenericNetServer&& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
AdcPosixGenericDaemon::operator=(std::move(other));
|
||||
AdcNetSessionManager::operator=(std::move(other));
|
||||
|
||||
_serverIdent = std::move(other._serverIdent);
|
||||
_stopListenFunc = std::move(other._stopListenFunc);
|
||||
|
||||
for (auto& func : other._moveCtorFunc) {
|
||||
func(this);
|
||||
}
|
||||
|
||||
_moveCtorFunc = std::move(other._moveCtorFunc);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual server_ident_t ident() const
|
||||
{
|
||||
@@ -214,6 +305,13 @@ public:
|
||||
|
||||
doAccept<SessionT>(acceptor, id, sess_ctx);
|
||||
}
|
||||
|
||||
// only once per SessionT
|
||||
if (_isListening<SessionT>[this].size() == 1) {
|
||||
_moveCtorFunc = [this](const AdcGenericNetServer* new_instance) {
|
||||
_isListening<SessionT>[new_instance] = std::move(_isListening<SessionT>[this]);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -247,6 +345,7 @@ protected:
|
||||
_isListening{};
|
||||
|
||||
std::vector<std::function<void()>> _stopListenFunc;
|
||||
std::vector<std::function<void(const AdcGenericNetServer*)>> _moveCtorFunc;
|
||||
|
||||
server_ident_t _serverIdent;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user