From: Maksym Mamontov Date: Tue, 23 Aug 2022 15:35:03 +0000 (+0300) Subject: Start replacing notifiers with subscriptions. X-Git-Url: https://git.stg.codes/stg.git/commitdiff_plain/ee1709cd231588fe672d0bd2546ef69ee87ff88c?hp=c59911ca3cd38cf4ab36d2cc62686f97395899f9 Start replacing notifiers with subscriptions. --- diff --git a/include/stg/subscriptions.h b/include/stg/subscriptions.h index 1486e62d..853cebe1 100644 --- a/include/stg/subscriptions.h +++ b/include/stg/subscriptions.h @@ -7,6 +7,48 @@ namespace STG { +class Connection +{ + public: + Connection() noexcept : m_connected(false) {} + + Connection(const Connection&) = delete; + Connection& operator=(const Connection&) = delete; + Connection(Connection&&) = default; + Connection& operator=(Connection&&) = default; + + Connection(const std::function& f) noexcept : m_disconnect(f), m_connected(true) {} + void disconnect() noexcept + { + if (!m_connected) + return; + m_disconnect(); + m_connected = false; + } + private: + std::function m_disconnect; + bool m_connected; +}; + +class ScopedConnection +{ + public: + ScopedConnection() = default; + + ScopedConnection(const ScopedConnection&) = delete; + ScopedConnection& operator=(const ScopedConnection&) = delete; + ScopedConnection(ScopedConnection&&) = default; + ScopedConnection& operator=(ScopedConnection&&) = default; + + ScopedConnection(Connection c) noexcept : m_conn(std::move(c)) {} + ~ScopedConnection() { disconnect(); } + + void disconnect() noexcept { m_conn.disconnect(); } + + private: + Connection m_conn; +}; + template class Subscriptions { @@ -14,35 +56,16 @@ class Subscriptions using Callback = std::function; using Callbacks = std::list; - class Connection + Connection makeConn(typename Callbacks::iterator i) noexcept { - public: - Connection(Subscriptions& s, typename Callbacks::iterator i) noexcept - : m_subscriptions(s), m_iterator(i), m_connected(true) - {} - ~Connection() - { - disconnect(); - } - - void disconnect() noexcept - { - if (!m_connected) - return; - m_subscriptions.remove(m_iterator); - m_connected = false; - } - private: - Subscriptions& m_subscriptions; - typename Callbacks::iterator m_iterator; - bool m_connected; - }; + return Connection([this, i](){ remove(i); }); + } template Connection add(F&& f) { std::lock_guard lock(m_mutex); - return Connection(*this, m_callbacks.insert(m_callbacks.end(), Callback(std::forward(f)))); + return makeConn(m_callbacks.insert(m_callbacks.end(), Callback(std::forward(f)))); } template diff --git a/include/stg/users.h b/include/stg/users.h index dfc60b64..a8d4eb60 100644 --- a/include/stg/users.h +++ b/include/stg/users.h @@ -20,7 +20,7 @@ #pragma once -#include "notifer.h" +#include "subscriptions.h" #include @@ -31,46 +31,51 @@ struct Admin; struct User; struct Auth; -struct Users { - virtual ~Users() = default; +class Users +{ + public: + virtual ~Users() = default; - using UserPtr = User*; - using ConstUserPtr = const User*; + using UserPtr = User*; + using ConstUserPtr = const User*; - virtual int FindByName(const std::string& login, UserPtr* user) = 0; - virtual int FindByName(const std::string& login, ConstUserPtr* user) const = 0; - virtual bool Exists(const std::string& login) const = 0; + virtual int FindByName(const std::string& login, UserPtr* user) = 0; + virtual int FindByName(const std::string& login, ConstUserPtr* user) const = 0; + virtual bool Exists(const std::string& login) const = 0; - virtual bool TariffInUse(const std::string& tariffName) const = 0; + virtual bool TariffInUse(const std::string& tariffName) const = 0; - virtual void AddNotifierUserAdd(NotifierBase* notifier) = 0; - virtual void DelNotifierUserAdd(NotifierBase* notifier) = 0; + template + auto onUserAdd(F&& f) { return m_onAddCallbacks.add(std::forward(f)); } + template + auto onUserDel(F&& f) { return m_onDelCallbacks.add(std::forward(f)); } - virtual void AddNotifierUserDel(NotifierBase* notifier) = 0; - virtual void DelNotifierUserDel(NotifierBase* notifier) = 0; + virtual int Add(const std::string& login, const Admin* admin) = 0; + virtual void Del(const std::string& login, const Admin* admin) = 0; - virtual int Add(const std::string& login, const Admin* admin) = 0; - virtual void Del(const std::string& login, const Admin* admin) = 0; + virtual bool Authorize(const std::string& login, uint32_t ip, + uint32_t enabledDirs, const Auth* auth) = 0; + virtual bool Unauthorize(const std::string& login, + const Auth* auth, + const std::string& reason = {}) = 0; - virtual bool Authorize(const std::string& login, uint32_t ip, - uint32_t enabledDirs, const Auth* auth) = 0; - virtual bool Unauthorize(const std::string& login, - const Auth* auth, - const std::string& reason = {}) = 0; + virtual int ReadUsers() = 0; + virtual size_t Count() const = 0; - virtual int ReadUsers() = 0; - virtual size_t Count() const = 0; + virtual int FindByIPIdx(uint32_t ip, User** user) const = 0; + virtual bool IsIPInIndex(uint32_t ip) const = 0; + virtual bool IsIPInUse(uint32_t ip, const std::string & login, const User** user) const = 0; - virtual int FindByIPIdx(uint32_t ip, User** user) const = 0; - virtual bool IsIPInIndex(uint32_t ip) const = 0; - virtual bool IsIPInUse(uint32_t ip, const std::string & login, const User** user) const = 0; + virtual unsigned int OpenSearch() = 0; + virtual int SearchNext(int handle, User** u) = 0; + virtual int CloseSearch(int handle) = 0; - virtual unsigned int OpenSearch() = 0; - virtual int SearchNext(int handle, User** u) = 0; - virtual int CloseSearch(int handle) = 0; + virtual int Start() = 0; + virtual int Stop() = 0; - virtual int Start() = 0; - virtual int Stop() = 0; + protected: + Subscriptions m_onAddCallbacks; + Subscriptions m_onDelCallbacks; }; } diff --git a/projects/stargazer/plugins/authorization/ao/ao.cpp b/projects/stargazer/plugins/authorization/ao/ao.cpp index 1145d679..d0be8dd5 100644 --- a/projects/stargazer/plugins/authorization/ao/ao.cpp +++ b/projects/stargazer/plugins/authorization/ao/ao.cpp @@ -48,8 +48,6 @@ return "Always Online authorizator v.1.0"; AUTH_AO::AUTH_AO() : users(NULL), isRunning(false), - onAddUserNotifier(*this), - onDelUserNotifier(*this), logger(STG::PluginLogger::get("auth_ao")) { } @@ -59,8 +57,8 @@ int AUTH_AO::Start() printfd(__FILE__, "AUTH_AO::Start()\n"); GetUsers(); -users->AddNotifierUserAdd(&onAddUserNotifier); -users->AddNotifierUserDel(&onDelUserNotifier); +m_onAddUserConn = users->onUserAdd([this](auto user){ AddUser(user); }); +m_onDelUserConn = users->onUserDel([this](auto user){ DelUser(user); }); std::for_each(userList.begin(), userList.end(), [this](auto user){ UpdateUserAuthorization(user); }); @@ -75,8 +73,8 @@ printfd(__FILE__, "AUTH_AO::Stop()\n"); if (!isRunning) return 0; -users->DelNotifierUserAdd(&onAddUserNotifier); -users->DelNotifierUserDel(&onDelUserNotifier); +m_onAddUserConn.disconnect(); +m_onDelUserConn.disconnect(); auto it = userList.begin(); while (it != userList.end()) diff --git a/projects/stargazer/plugins/authorization/ao/ao.h b/projects/stargazer/plugins/authorization/ao/ao.h index a97a0918..18b41429 100644 --- a/projects/stargazer/plugins/authorization/ao/ao.h +++ b/projects/stargazer/plugins/authorization/ao/ao.h @@ -24,6 +24,7 @@ #include "stg/module_settings.h" #include "stg/store.h" #include "stg/notifer.h" +#include "stg/subscriptions.h" #include "stg/user_ips.h" #include "stg/user.h" #include "stg/logger.h" @@ -121,31 +122,8 @@ private: std::list > BeforeChgIPNotifierList; std::list > AfterChgIPNotifierList; - class ADD_USER_NONIFIER: public STG::NotifierBase { - public: - explicit ADD_USER_NONIFIER(AUTH_AO & a) : auth(a) {} - virtual ~ADD_USER_NONIFIER() {} - void notify(const UserPtr & user) override { auth.AddUser(user); } - - private: - ADD_USER_NONIFIER(const ADD_USER_NONIFIER & rvalue); - ADD_USER_NONIFIER & operator=(const ADD_USER_NONIFIER & rvalue); - - AUTH_AO & auth; - } onAddUserNotifier; - - class DEL_USER_NONIFIER: public STG::NotifierBase { - public: - explicit DEL_USER_NONIFIER(AUTH_AO & a) : auth(a) {} - virtual ~DEL_USER_NONIFIER() {} - void notify(const UserPtr & user) override { auth.DelUser(user); } - - private: - DEL_USER_NONIFIER(const DEL_USER_NONIFIER & rvalue); - DEL_USER_NONIFIER & operator=(const DEL_USER_NONIFIER & rvalue); - - AUTH_AO & auth; - } onDelUserNotifier; + STG::ScopedConnection m_onAddUserConn; + STG::ScopedConnection m_onDelUserConn; STG::PluginLogger logger; diff --git a/projects/stargazer/plugins/authorization/inetaccess/inetaccess.cpp b/projects/stargazer/plugins/authorization/inetaccess/inetaccess.cpp index 01162875..3c6a687c 100644 --- a/projects/stargazer/plugins/authorization/inetaccess/inetaccess.cpp +++ b/projects/stargazer/plugins/authorization/inetaccess/inetaccess.cpp @@ -290,7 +290,6 @@ AUTH_IA::AUTH_IA() stgSettings(NULL), listenSocket(-1), enabledDirs(0xFFffFFff), - onDelUserNotifier(*this), logger(STG::PluginLogger::get("auth_ia")) { InitContext("pr7Hhen", 7, &ctxS); @@ -341,12 +340,10 @@ AUTH_IA::~AUTH_IA() //----------------------------------------------------------------------------- int AUTH_IA::Start() { -users->AddNotifierUserDel(&onDelUserNotifier); +m_onDelUserConn = users->onUserDel([this](auto user){ DelUser(user); }); if (PrepareNet()) - { return -1; - } if (!m_thread.joinable()) m_thread = std::jthread([this](auto token){ Run(std::move(token)); }); @@ -394,7 +391,7 @@ if (isRunningRunTimeouter) } } -users->DelNotifierUserDel(&onDelUserNotifier); +m_onDelUserConn.disconnect(); if (isRunningRun) m_thread.detach(); diff --git a/projects/stargazer/plugins/authorization/inetaccess/inetaccess.h b/projects/stargazer/plugins/authorization/inetaccess/inetaccess.h index f9137c20..d620f392 100644 --- a/projects/stargazer/plugins/authorization/inetaccess/inetaccess.h +++ b/projects/stargazer/plugins/authorization/inetaccess/inetaccess.h @@ -213,21 +213,7 @@ private: class AUTH_IA; using UserPtr = STG::User*; //----------------------------------------------------------------------------- -class DEL_USER_NOTIFIER: public STG::NotifierBase { -public: - explicit DEL_USER_NOTIFIER(AUTH_IA & a) : auth(a) {} - virtual ~DEL_USER_NOTIFIER() {} - - void notify(const UserPtr & user) override; -private: - DEL_USER_NOTIFIER(const DEL_USER_NOTIFIER & rvalue); - DEL_USER_NOTIFIER & operator=(const DEL_USER_NOTIFIER & rvalue); - - AUTH_IA & auth; -}; -//----------------------------------------------------------------------------- class AUTH_IA : public STG::Auth { -friend class DEL_USER_NOTIFIER; public: AUTH_IA(); ~AUTH_IA() override; @@ -350,7 +336,7 @@ private: uint32_t enabledDirs; - DEL_USER_NOTIFIER onDelUserNotifier; + STG::ScopedConnection m_onDelUserConn; STG::PluginLogger logger; @@ -370,9 +356,3 @@ class UnauthorizeUser : std::unary_function & AUTH_IA * auth; }; -//----------------------------------------------------------------------------- -inline -void DEL_USER_NOTIFIER::notify(const UserPtr & user) -{ - auth.DelUser(user); -} diff --git a/projects/stargazer/plugins/other/ping/ping.cpp b/projects/stargazer/plugins/other/ping/ping.cpp index 35237120..65dd3454 100644 --- a/projects/stargazer/plugins/other/ping/ping.cpp +++ b/projects/stargazer/plugins/other/ping/ping.cpp @@ -63,8 +63,6 @@ return 0; PING::PING() : users(nullptr), isRunning(false), - onAddUserNotifier(*this), - onDelUserNotifier(*this), logger(STG::PluginLogger::get("ping")) { } @@ -81,8 +79,8 @@ int PING::Start() { GetUsers(); -users->AddNotifierUserAdd(&onAddUserNotifier); -users->AddNotifierUserDel(&onDelUserNotifier); +m_onAddUserConn = users->onUserAdd([this](auto user){ AddUser(user); }); +m_onDelUserConn = users->onUserDel([this](auto user){ DelUser(user); }); pinger.SetDelayTime(pingSettings.GetPingDelay()); pinger.Start(); @@ -111,8 +109,8 @@ for (int i = 0; i < 25; i++) nanosleep(&ts, nullptr); } -users->DelNotifierUserAdd(&onAddUserNotifier); -users->DelNotifierUserDel(&onDelUserNotifier); +m_onAddUserConn.disconnect(); +m_onDelUserConn.disconnect(); std::list::iterator users_iter; users_iter = usersList.begin(); @@ -306,14 +304,3 @@ if (oldIPS.onlyOneIP()) if (newIPS.onlyOneIP()) ping.pinger.AddIP(newIPS[0].ip); } -//----------------------------------------------------------------------------- -void ADD_USER_NONIFIER_PING::notify(const UserPtr & user) -{ -ping.AddUser(user); -} -//----------------------------------------------------------------------------- -void DEL_USER_NONIFIER_PING::notify(const UserPtr & user) -{ -ping.DelUser(user); -} -//----------------------------------------------------------------------------- diff --git a/projects/stargazer/plugins/other/ping/ping.h b/projects/stargazer/plugins/other/ping/ping.h index ff66a1c2..68d79794 100644 --- a/projects/stargazer/plugins/other/ping/ping.h +++ b/projects/stargazer/plugins/other/ping/ping.h @@ -3,6 +3,7 @@ #include "stg/plugin.h" #include "stg/module_settings.h" #include "stg/notifer.h" +#include "stg/subscriptions.h" #include "stg/user_ips.h" #include "stg/pinger.h" #include "stg/users.h" @@ -55,30 +56,6 @@ private: const PING & ping; }; //----------------------------------------------------------------------------- -class ADD_USER_NONIFIER_PING: public STG::NotifierBase { -public: - explicit ADD_USER_NONIFIER_PING(PING & p) : ping(p) {} - void notify(const UserPtr & user) override; - -private: - ADD_USER_NONIFIER_PING(const ADD_USER_NONIFIER_PING &); - ADD_USER_NONIFIER_PING & operator=(const ADD_USER_NONIFIER_PING &); - - PING & ping; -}; -//----------------------------------------------------------------------------- -class DEL_USER_NONIFIER_PING: public STG::NotifierBase { -public: - explicit DEL_USER_NONIFIER_PING(PING & p) : ping(p) {} - void notify(const UserPtr & user) override; - -private: - DEL_USER_NONIFIER_PING(const DEL_USER_NONIFIER_PING &); - DEL_USER_NONIFIER_PING & operator=(const DEL_USER_NONIFIER_PING &); - - PING & ping; -}; -//----------------------------------------------------------------------------- class PING_SETTINGS { public: PING_SETTINGS() : pingDelay(0) {} @@ -136,8 +113,8 @@ private: std::list ChgCurrIPNotifierList; std::list ChgIPNotifierList; - ADD_USER_NONIFIER_PING onAddUserNotifier; - DEL_USER_NONIFIER_PING onDelUserNotifier; + STG::ScopedConnection m_onAddUserConn; + STG::ScopedConnection m_onDelUserConn; STG::PluginLogger logger; }; diff --git a/projects/stargazer/plugins/other/rscript/rscript.cpp b/projects/stargazer/plugins/other/rscript/rscript.cpp index 7f0f4bc4..d54c800e 100644 --- a/projects/stargazer/plugins/other/rscript/rscript.cpp +++ b/projects/stargazer/plugins/other/rscript/rscript.cpp @@ -160,8 +160,6 @@ REMOTE_SCRIPT::REMOTE_SCRIPT() isRunning(false), users(nullptr), sock(0), - onAddUserNotifier(*this), - onDelUserNotifier(*this), logger(STG::PluginLogger::get("rscript")) { } @@ -201,8 +199,8 @@ netRouters = rsSettings.GetSubnetsMap(); InitEncrypt(rsSettings.GetPassword()); -users->AddNotifierUserAdd(&onAddUserNotifier); -users->AddNotifierUserDel(&onDelUserNotifier); +m_onAddUserConn = users->onUserAdd([this](auto user){ AddUser(user); }); +m_onDelUserConn = users->onUserDel([this](auto user){ DelUser(user); }); if (GetUsers()) return -1; @@ -242,9 +240,6 @@ if (isRunning) } } -users->DelNotifierUserDel(&onDelUserNotifier); -users->DelNotifierUserAdd(&onAddUserNotifier); - if (isRunning) { logger("Cannot stop thread."); diff --git a/projects/stargazer/plugins/other/rscript/rscript.h b/projects/stargazer/plugins/other/rscript/rscript.h index fc957108..d0bf1e7e 100644 --- a/projects/stargazer/plugins/other/rscript/rscript.h +++ b/projects/stargazer/plugins/other/rscript/rscript.h @@ -23,6 +23,7 @@ #include "stg/plugin.h" #include "stg/module_settings.h" +#include "stg/subscriptions.h" #include "stg/notifer.h" #include "stg/user.h" #include "stg/blowfish.h" @@ -58,32 +59,6 @@ class DisconnectUser; using UserPtr = STG::User*; -//----------------------------------------------------------------------------- -class ADD_USER_NONIFIER: public STG::NotifierBase { -public: - explicit ADD_USER_NONIFIER(REMOTE_SCRIPT & r) - : rs(r) {} - void notify(const UserPtr & user) override; - -private: - ADD_USER_NONIFIER(const ADD_USER_NONIFIER & rhs); - ADD_USER_NONIFIER & operator=(const ADD_USER_NONIFIER); - - REMOTE_SCRIPT & rs; -}; -//----------------------------------------------------------------------------- -class DEL_USER_NONIFIER: public STG::NotifierBase { -public: - explicit DEL_USER_NONIFIER(REMOTE_SCRIPT & r) - : rs(r) {} - void notify(const UserPtr & user) override; - -private: - DEL_USER_NONIFIER(const DEL_USER_NONIFIER & rhs); - DEL_USER_NONIFIER & operator=(const DEL_USER_NONIFIER); - - REMOTE_SCRIPT & rs; -}; //----------------------------------------------------------------------------- class IP_NOTIFIER: public STG::PropertyNotifierBase { public: @@ -243,8 +218,8 @@ private: int sock; - ADD_USER_NONIFIER onAddUserNotifier; - DEL_USER_NONIFIER onDelUserNotifier; + STG::ScopedConnection m_onAddUserConn; + STG::ScopedConnection m_onDelUserConn; STG::PluginLogger logger; @@ -264,15 +239,5 @@ class DisconnectUser : public std::unary_functionSearchNext(h, &u) == 0) users->CloseSearch(h); -users->AddNotifierUserAdd(&addUserNotifier); -users->AddNotifierUserDel(&delUserNotifier); +m_onAddUserConn = users->onUserAdd([this](auto user){ + SetNotifier(user); + UpdateTables(); +}); +m_onDelUserConn = users->onUserDel([this](auto user){ + UnsetNotifier(user); + UpdateTables(); +}); tariffs->AddNotifierAdd(&addDelTariffNotifier); tariffs->AddNotifierDel(&addDelTariffNotifier); @@ -456,8 +460,8 @@ void SMUX::ResetNotifiers() tariffs->DelNotifierDel(&addDelTariffNotifier); tariffs->DelNotifierAdd(&addDelTariffNotifier); -users->DelNotifierUserDel(&delUserNotifier); -users->DelNotifierUserAdd(&addUserNotifier); +m_onAddUserConn.disconnect(); +m_onDelUserConn.disconnect(); auto it = notifiers.begin(); while (it != notifiers.end()) diff --git a/projects/stargazer/plugins/other/smux/smux.h b/projects/stargazer/plugins/other/smux/smux.h index f45beffc..1986d28b 100644 --- a/projects/stargazer/plugins/other/smux/smux.h +++ b/projects/stargazer/plugins/other/smux/smux.h @@ -1,28 +1,28 @@ -#ifndef __SMUX_H__ -#define __SMUX_H__ +#pragma once -#include -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshadow" -#include -#pragma GCC diagnostic pop -#include +#include "sensors.h" +#include "tables.h" +#include "types.h" #include "stg/SMUX-PDUs.h" #include "stg/ObjectSyntax.h" #include "stg/plugin.h" #include "stg/module_settings.h" +#include "stg/subscriptions.h" #include "stg/notifer.h" #include "stg/noncopyable.h" #include "stg/logger.h" -#include "sensors.h" -#include "tables.h" -#include "types.h" +#include +#include +#include +#include +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#include +#pragma GCC diagnostic pop +#include namespace STG { @@ -87,24 +87,6 @@ public: : STG::NotifierBase(), smux(s) {} void notify(const STG::TariffData &) override; -private: - SMUX & smux; -}; -//----------------------------------------------------------------------------- -class ADD_USER_NOTIFIER : public STG::NotifierBase { -public: - explicit ADD_USER_NOTIFIER(SMUX & s) : STG::NotifierBase(), smux(s) {} - void notify(const UserPtr &) override; - -private: - SMUX & smux; -}; -//----------------------------------------------------------------------------- -class DEL_USER_NOTIFIER : public STG::NotifierBase { -public: - explicit DEL_USER_NOTIFIER(SMUX & s) : STG::NotifierBase(), smux(s) {} - void notify(const UserPtr &) override; - private: SMUX & smux; }; @@ -186,9 +168,10 @@ private: Sensors sensors; Tables tables; + STG::ScopedConnection m_onAddUserConn; + STG::ScopedConnection m_onDelUserConn; + std::list notifiers; - ADD_USER_NOTIFIER addUserNotifier; - DEL_USER_NOTIFIER delUserNotifier; ADD_DEL_TARIFF_NOTIFIER addDelTariffNotifier; STG::PluginLogger logger; @@ -206,19 +189,3 @@ void ADD_DEL_TARIFF_NOTIFIER::notify(const STG::TariffData &) { smux.UpdateTables(); } - -inline -void ADD_USER_NOTIFIER::notify(const UserPtr & userPtr) -{ -smux.SetNotifier(userPtr); -smux.UpdateTables(); -} - -inline -void DEL_USER_NOTIFIER::notify(const UserPtr & userPtr) -{ -smux.UnsetNotifier(userPtr); -smux.UpdateTables(); -} - -#endif diff --git a/projects/stargazer/traffcounter_impl.cpp b/projects/stargazer/traffcounter_impl.cpp index ed0f93d5..aa156c9d 100644 --- a/projects/stargazer/traffcounter_impl.cpp +++ b/projects/stargazer/traffcounter_impl.cpp @@ -53,8 +53,6 @@ using STG::TraffCounterImpl; using STG::TRF_IP_BEFORE; using STG::TRF_IP_AFTER; -using STG::ADD_USER_NONIFIER; -using STG::DEL_USER_NONIFIER; namespace AsyncPoolST = STG::AsyncPoolST; @@ -73,17 +71,20 @@ TraffCounterImpl::TraffCounterImpl(UsersImpl * u, const std::string & fn) monitoring(false), touchTimeP(stgTime - MONITOR_TIME_DELAY_SEC), users(u), - stopped(true), - addUserNotifier(*this), - delUserNotifier(*this) + stopped(true) { for (int i = 0; i < DIR_NUM; i++) strprintf(&dirName[i], "DIR%d", i); dirName[DIR_NUM] = "NULL"; -users->AddNotifierUserAdd(&addUserNotifier); -users->AddNotifierUserDel(&delUserNotifier); +m_onAddUserConn = users->onUserImplAdd([this](auto user){ + AsyncPoolST::enqueue([this, user](){ SetUserNotifiers(user); }); +}); +m_onDelUserConn = users->onUserImplDel([this](auto user){ + AsyncPoolST::enqueue([this, user](){ UnSetUserNotifiers(user); }); + AsyncPoolST::enqueue([this, user](){ DelUser(user->GetCurrIP()); }); +}); } //----------------------------------------------------------------------------- TraffCounterImpl::~TraffCounterImpl() @@ -868,14 +869,3 @@ if (!newValue) AsyncPoolST::enqueue([this](){ traffCnt.AddUser(user); }); } //----------------------------------------------------------------------------- -void ADD_USER_NONIFIER::notify(const UserImplPtr & user) -{ -AsyncPoolST::enqueue([this, user](){ traffCnt.SetUserNotifiers(user); }); -} -//----------------------------------------------------------------------------- -void DEL_USER_NONIFIER::notify(const UserImplPtr & user) -{ -AsyncPoolST::enqueue([this, user](){ traffCnt.UnSetUserNotifiers(user); }); -AsyncPoolST::enqueue([this, user](){ traffCnt.DelUser(user->GetCurrIP()); }); -} -//----------------------------------------------------------------------------- diff --git a/projects/stargazer/traffcounter_impl.h b/projects/stargazer/traffcounter_impl.h index 7fd06309..474b6694 100644 --- a/projects/stargazer/traffcounter_impl.h +++ b/projects/stargazer/traffcounter_impl.h @@ -23,7 +23,7 @@ #include "stg/traffcounter.h" #include "stg/logger.h" #include "stg/raw_ip_packet.h" -#include "stg/noncopyable.h" +#include "stg/subscriptions.h" #include "stg/notifer.h" #include "user_impl.h" @@ -130,41 +130,7 @@ private: using UserImplPtr = UserImpl*; //----------------------------------------------------------------------------- -class ADD_USER_NONIFIER: public NotifierBase { -public: - explicit ADD_USER_NONIFIER(TraffCounterImpl & t) : - NotifierBase(), - traffCnt(t) - {} - virtual ~ADD_USER_NONIFIER() {} - void notify(const UserImplPtr & user) override; - -private: - ADD_USER_NONIFIER(const ADD_USER_NONIFIER & rvalue); - ADD_USER_NONIFIER & operator=(const ADD_USER_NONIFIER & rvalue); - - TraffCounterImpl & traffCnt; -}; -//----------------------------------------------------------------------------- -class DEL_USER_NONIFIER: public NotifierBase { -public: - explicit DEL_USER_NONIFIER(TraffCounterImpl & t) : - NotifierBase(), - traffCnt(t) - {} - virtual ~DEL_USER_NONIFIER() {} - void notify(const UserImplPtr & user) override; - -private: - DEL_USER_NONIFIER(const DEL_USER_NONIFIER & rvalue); - DEL_USER_NONIFIER & operator=(const DEL_USER_NONIFIER & rvalue); - - TraffCounterImpl & traffCnt; -}; -//----------------------------------------------------------------------------- class TraffCounterImpl : public TraffCounter { - friend class ADD_USER_NONIFIER; - friend class DEL_USER_NONIFIER; friend class TRF_IP_BEFORE; friend class TRF_IP_AFTER; public: @@ -228,11 +194,11 @@ class TraffCounterImpl : public TraffCounter { std::mutex m_mutex; std::jthread m_thread; + ScopedConnection m_onAddUserConn; + ScopedConnection m_onDelUserConn; + std::list ipBeforeNotifiers; std::list ipAfterNotifiers; - - ADD_USER_NONIFIER addUserNotifier; - DEL_USER_NONIFIER delUserNotifier; }; } diff --git a/projects/stargazer/users_impl.cpp b/projects/stargazer/users_impl.cpp index cfd692c5..5bf082ec 100644 --- a/projects/stargazer/users_impl.cpp +++ b/projects/stargazer/users_impl.cpp @@ -148,26 +148,8 @@ u.OnAdd(); users.push_front(u); AddUserIntoIndexes(users.begin()); - - { - // Fire all "on add" notifiers - auto ni = onAddNotifiers.begin(); - while (ni != onAddNotifiers.end()) - { - (*ni)->notify(&users.front()); - ++ni; - } - } - - { - // Fire all "on add" implementation notifiers - auto ni = onAddNotifiersImpl.begin(); - while (ni != onAddNotifiersImpl.end()) - { - (*ni)->notify(&users.front()); - ++ni; - } - } +m_onAddCallbacks.notify(&users.front()); +m_onAddImplCallbacks.notify(&users.front()); return 0; } @@ -199,23 +181,8 @@ if (priv.userAddDel == 0) u->SetDeleted(); } - { - auto ni = onDelNotifiers.begin(); - while (ni != onDelNotifiers.end()) - { - (*ni)->notify(&(*u)); - ++ni; - } - } - - { - auto ni = onDelNotifiersImpl.begin(); - while (ni != onDelNotifiersImpl.end()) - { - (*ni)->notify(&(*u)); - ++ni; - } - } + m_onDelCallbacks.notify(&(*u)); + m_onDelImplCallbacks.notify(&(*u)); { std::lock_guard lock(m_mutex); @@ -664,54 +631,6 @@ while (iter != users.end()) return false; } //----------------------------------------------------------------------------- -void UsersImpl::AddNotifierUserAdd(NotifierBase * n) -{ -std::lock_guard lock(m_mutex); -onAddNotifiers.insert(n); -} -//----------------------------------------------------------------------------- -void UsersImpl::DelNotifierUserAdd(NotifierBase * n) -{ -std::lock_guard lock(m_mutex); -onAddNotifiers.erase(n); -} -//----------------------------------------------------------------------------- -void UsersImpl::AddNotifierUserDel(NotifierBase * n) -{ -std::lock_guard lock(m_mutex); -onDelNotifiers.insert(n); -} -//----------------------------------------------------------------------------- -void UsersImpl::DelNotifierUserDel(NotifierBase * n) -{ -std::lock_guard lock(m_mutex); -onDelNotifiers.erase(n); -} -//----------------------------------------------------------------------------- -void UsersImpl::AddNotifierUserAdd(NotifierBase * n) -{ -std::lock_guard lock(m_mutex); -onAddNotifiersImpl.insert(n); -} -//----------------------------------------------------------------------------- -void UsersImpl::DelNotifierUserAdd(NotifierBase * n) -{ -std::lock_guard lock(m_mutex); -onAddNotifiersImpl.erase(n); -} -//----------------------------------------------------------------------------- -void UsersImpl::AddNotifierUserDel(NotifierBase * n) -{ -std::lock_guard lock(m_mutex); -onDelNotifiersImpl.insert(n); -} -//----------------------------------------------------------------------------- -void UsersImpl::DelNotifierUserDel(NotifierBase * n) -{ -std::lock_guard lock(m_mutex); -onDelNotifiersImpl.erase(n); -} -//----------------------------------------------------------------------------- unsigned int UsersImpl::OpenSearch() { std::lock_guard lock(m_mutex); diff --git a/projects/stargazer/users_impl.h b/projects/stargazer/users_impl.h index cd7d2932..b5a37063 100644 --- a/projects/stargazer/users_impl.h +++ b/projects/stargazer/users_impl.h @@ -64,109 +64,101 @@ std::list::iterator iter; time_t delTime; }; //----------------------------------------------------------------------------- -class UsersImpl : public Users { +class UsersImpl : public Users +{ friend class PROPERTY_NOTIFER_IP_BEFORE; friend class PROPERTY_NOTIFER_IP_AFTER; -public: - using UserImplPtr = UserImpl*; - - UsersImpl(SettingsImpl * s, Store * store, - Tariffs * tariffs, Services & svcs, - const Admin& sysAdmin); - - int FindByName(const std::string & login, UserPtr * user) override; - int FindByName(const std::string & login, ConstUserPtr * user) const override; - bool Exists(const std::string & login) const override; - - bool TariffInUse(const std::string & tariffName) const override; + public: + using UserImplPtr = UserImpl*; - void AddNotifierUserAdd(NotifierBase *) override; - void DelNotifierUserAdd(NotifierBase *) override; + UsersImpl(SettingsImpl * s, Store * store, + Tariffs * tariffs, Services & svcs, + const Admin& sysAdmin); - void AddNotifierUserDel(NotifierBase *) override; - void DelNotifierUserDel(NotifierBase *) override; + int FindByName(const std::string & login, UserPtr * user) override; + int FindByName(const std::string & login, ConstUserPtr * user) const override; + bool Exists(const std::string & login) const override; - void AddNotifierUserAdd(NotifierBase *); - void DelNotifierUserAdd(NotifierBase *); + bool TariffInUse(const std::string & tariffName) const override; - void AddNotifierUserDel(NotifierBase *); - void DelNotifierUserDel(NotifierBase *); + template + auto onUserImplAdd(F&& f) { return m_onAddImplCallbacks.add(std::forward(f)); } + template + auto onUserImplDel(F&& f) { return m_onDelImplCallbacks.add(std::forward(f)); } - int Add(const std::string & login, const Admin * admin) override; - void Del(const std::string & login, const Admin * admin) override; + int Add(const std::string & login, const Admin * admin) override; + void Del(const std::string & login, const Admin * admin) override; - bool Authorize(const std::string & login, uint32_t ip, - uint32_t enabledDirs, const Auth * auth) override; - bool Unauthorize(const std::string & login, - const Auth * auth, - const std::string & reason) override; + bool Authorize(const std::string & login, uint32_t ip, + uint32_t enabledDirs, const Auth * auth) override; + bool Unauthorize(const std::string & login, + const Auth * auth, + const std::string & reason) override; - int ReadUsers() override; - size_t Count() const override { return users.size(); } + int ReadUsers() override; + size_t Count() const override { return users.size(); } - int FindByIPIdx(uint32_t ip, UserPtr * user) const override; - int FindByIPIdx(uint32_t ip, UserImpl ** user) const; - bool IsIPInIndex(uint32_t ip) const override; - bool IsIPInUse(uint32_t ip, const std::string & login, ConstUserPtr * user) const override; + int FindByIPIdx(uint32_t ip, UserPtr * user) const override; + int FindByIPIdx(uint32_t ip, UserImpl ** user) const; + bool IsIPInIndex(uint32_t ip) const override; + bool IsIPInUse(uint32_t ip, const std::string & login, ConstUserPtr * user) const override; - unsigned int OpenSearch() override; - int SearchNext(int handler, UserPtr * user) override; - int SearchNext(int handler, UserImpl ** user); - int CloseSearch(int handler) override; + unsigned int OpenSearch() override; + int SearchNext(int handler, UserPtr * user) override; + int SearchNext(int handler, UserImpl ** user); + int CloseSearch(int handler) override; - int Start() override; - int Stop() override; + int Start() override; + int Stop() override; -private: - UsersImpl(const UsersImpl & rvalue); - UsersImpl & operator=(const UsersImpl & rvalue); + private: + UsersImpl(const UsersImpl & rvalue); + UsersImpl & operator=(const UsersImpl & rvalue); - void AddToIPIdx(user_iter user); - void DelFromIPIdx(uint32_t ip); - bool FindByIPIdx(uint32_t ip, user_iter & iter) const; + void AddToIPIdx(user_iter user); + void DelFromIPIdx(uint32_t ip); + bool FindByIPIdx(uint32_t ip, user_iter & iter) const; - bool FindByNameNonLock(const std::string & login, user_iter * user); - bool FindByNameNonLock(const std::string & login, const_user_iter * user) const; + bool FindByNameNonLock(const std::string & login, user_iter * user); + bool FindByNameNonLock(const std::string & login, const_user_iter * user) const; - void RealDelUser(); - void ProcessActions(); + void RealDelUser(); + void ProcessActions(); - void AddUserIntoIndexes(user_iter user); - void DelUserFromIndexes(user_iter user); + void AddUserIntoIndexes(user_iter user); + void DelUserFromIndexes(user_iter user); - void Run(std::stop_token token); - void NewMinute(const struct tm & t); - void NewDay(const struct tm & t); - void DayResetTraff(const struct tm & t); + void Run(std::stop_token token); + void NewMinute(const struct tm & t); + void NewDay(const struct tm & t); + void DayResetTraff(const struct tm & t); - bool TimeToWriteDetailStat(const struct tm & t); + bool TimeToWriteDetailStat(const struct tm & t); - std::list users; - std::list usersToDelete; + std::list users; + std::list usersToDelete; - std::map ipIndex; - std::map loginIndex; + std::map ipIndex; + std::map loginIndex; - SettingsImpl * settings; - Tariffs * m_tariffs; - Services & m_services; - Store * m_store; - const Admin& m_sysAdmin; - Logger & WriteServLog; + SettingsImpl * settings; + Tariffs * m_tariffs; + Services & m_services; + Store * m_store; + const Admin& m_sysAdmin; + Logger & WriteServLog; - bool isRunning; + bool isRunning; - mutable std::mutex m_mutex; - std::jthread m_thread; - mutable unsigned int handle; + mutable std::mutex m_mutex; + std::jthread m_thread; + mutable unsigned int handle; - mutable std::map searchDescriptors; + mutable std::map searchDescriptors; - std::set*> onAddNotifiers; - std::set*> onDelNotifiers; - std::set*> onAddNotifiersImpl; - std::set*> onDelNotifiersImpl; + Subscriptions m_onAddImplCallbacks; + Subscriptions m_onDelImplCallbacks; }; } diff --git a/tests/test_subscriptions.cpp b/tests/test_subscriptions.cpp index ebc3c920..50780927 100644 --- a/tests/test_subscriptions.cpp +++ b/tests/test_subscriptions.cpp @@ -10,6 +10,9 @@ #include #pragma GCC diagnostic pop +using STG::Subscriptions; +using STG::ScopedConnection; + namespace { @@ -37,19 +40,19 @@ struct Receiver } -BOOST_AUTO_TEST_SUITE(Subscriptions) +BOOST_AUTO_TEST_SUITE(TestSubscriptions) BOOST_AUTO_TEST_CASE(Construction) { - STG::Subscriptions<> nullary; + Subscriptions<> nullary; BOOST_CHECK(nullary.empty()); BOOST_CHECK_EQUAL(nullary.size(), 0); - STG::Subscriptions unary; + Subscriptions unary; BOOST_CHECK(unary.empty()); BOOST_CHECK_EQUAL(unary.size(), 0); - STG::Subscriptions binary; + Subscriptions binary; BOOST_CHECK(binary.empty()); BOOST_CHECK_EQUAL(binary.size(), 0); } @@ -57,10 +60,10 @@ BOOST_AUTO_TEST_CASE(Construction) BOOST_AUTO_TEST_CASE(AddingAndRemoving) { Receiver r; - STG::Subscriptions<> nullary; + Subscriptions<> nullary; { - auto c1 = nullary.add(r, &Receiver::r0); - auto c2 = nullary.add([&r](){ r.r0(); }); + ScopedConnection c1 = nullary.add(r, &Receiver::r0); + ScopedConnection c2 = nullary.add([&r](){ r.r0(); }); BOOST_CHECK(!nullary.empty()); BOOST_CHECK_EQUAL(nullary.size(), 2); @@ -73,10 +76,10 @@ BOOST_AUTO_TEST_CASE(AddingAndRemoving) BOOST_CHECK(nullary.empty()); BOOST_CHECK_EQUAL(nullary.size(), 0); - STG::Subscriptions unary; + Subscriptions unary; { - auto c1 = unary.add(r, &Receiver::r1); - auto c2 = unary.add([&r](const auto& v){ r.r1(v); }); + ScopedConnection c1 = unary.add(r, &Receiver::r1); + ScopedConnection c2 = unary.add([&r](const auto& v){ r.r1(v); }); BOOST_CHECK(!unary.empty()); BOOST_CHECK_EQUAL(unary.size(), 2); @@ -89,10 +92,10 @@ BOOST_AUTO_TEST_CASE(AddingAndRemoving) BOOST_CHECK(unary.empty()); BOOST_CHECK_EQUAL(unary.size(), 0); - STG::Subscriptions binary; + Subscriptions binary; { - auto c1 = binary.add(r, &Receiver::r2); - auto c2 = binary.add([&r](const auto& v1, const auto& v2){ r.r2(v1, v2); }); + ScopedConnection c1 = binary.add(r, &Receiver::r2); + ScopedConnection c2 = binary.add([&r](const auto& v1, const auto& v2){ r.r2(v1, v2); }); BOOST_CHECK(!binary.empty()); BOOST_CHECK_EQUAL(binary.size(), 2); @@ -117,10 +120,10 @@ BOOST_AUTO_TEST_CASE(Notification) BOOST_CHECK_EQUAL(r.value1R2, 0); BOOST_CHECK_EQUAL(r.value2R2, ""); - STG::Subscriptions<> nullary; + Subscriptions<> nullary; { - auto c1 = nullary.add(r, &Receiver::r0); - auto c2 = nullary.add([&r](){ r.r0(); }); + ScopedConnection c1 = nullary.add(r, &Receiver::r0); + ScopedConnection c2 = nullary.add([&r](){ r.r0(); }); nullary.notify(); @@ -151,10 +154,10 @@ BOOST_AUTO_TEST_CASE(Notification) BOOST_CHECK_EQUAL(r.value1R2, 0); BOOST_CHECK_EQUAL(r.value2R2, ""); - STG::Subscriptions unary; + Subscriptions unary; { - auto c1 = unary.add(r, &Receiver::r1); - auto c2 = unary.add([&r](const auto& v){ r.r1(v); }); + ScopedConnection c1 = unary.add(r, &Receiver::r1); + ScopedConnection c2 = unary.add([&r](const auto& v){ r.r1(v); }); unary.notify(42); @@ -185,10 +188,10 @@ BOOST_AUTO_TEST_CASE(Notification) BOOST_CHECK_EQUAL(r.value1R2, 0); BOOST_CHECK_EQUAL(r.value2R2, ""); - STG::Subscriptions binary; + Subscriptions binary; { - auto c1 = binary.add(r, &Receiver::r2); - auto c2 = binary.add([&r](const auto& v1, const auto& v2){ r.r2(v1, v2); }); + ScopedConnection c1 = binary.add(r, &Receiver::r2); + ScopedConnection c2 = binary.add([&r](const auto& v1, const auto& v2){ r.r2(v1, v2); }); binary.notify(42, "Douglas"); diff --git a/tests/testusers.h b/tests/testusers.h index adc0507e..c2f5da34 100644 --- a/tests/testusers.h +++ b/tests/testusers.h @@ -17,12 +17,6 @@ struct TestUsers : public STG::Users bool TariffInUse(const std::string& /*tariffName*/) const override { return -1; } - void AddNotifierUserAdd(STG::NotifierBase* /*notifier*/) override {} - void DelNotifierUserAdd(STG::NotifierBase* /*notifier*/) override {} - - void AddNotifierUserDel(STG::NotifierBase* /*notifier*/) override {} - void DelNotifierUserDel(STG::NotifierBase* /*notifier*/) override {} - int Add(const std::string& /*login*/, const STG::Admin* /*admin*/) override { return 0; } void Del(const std::string& /*login*/, const STG::Admin* /*admin*/) override {}