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<void ()>& f) noexcept : m_disconnect(f), m_connected(true) {}
+ void disconnect() noexcept
+ {
+ if (!m_connected)
+ return;
+ m_disconnect();
+ m_connected = false;
+ }
+ private:
+ std::function<void ()> 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 <typename... Ts>
class Subscriptions
{
using Callback = std::function<void (Ts...)>;
using Callbacks = std::list<Callback>;
- 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 <typename F>
Connection add(F&& f)
{
std::lock_guard lock(m_mutex);
- return Connection(*this, m_callbacks.insert(m_callbacks.end(), Callback(std::forward<F>(f))));
+ return makeConn(m_callbacks.insert(m_callbacks.end(), Callback(std::forward<F>(f))));
}
template <typename C, typename... T2s>
#pragma once
-#include "notifer.h"
+#include "subscriptions.h"
#include <string>
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<User*>* notifier) = 0;
- virtual void DelNotifierUserAdd(NotifierBase<User*>* notifier) = 0;
+ template <typename F>
+ auto onUserAdd(F&& f) { return m_onAddCallbacks.add(std::forward<F>(f)); }
+ template <typename F>
+ auto onUserDel(F&& f) { return m_onDelCallbacks.add(std::forward<F>(f)); }
- virtual void AddNotifierUserDel(NotifierBase<User*>* notifier) = 0;
- virtual void DelNotifierUserDel(NotifierBase<User*>* 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<UserPtr> m_onAddCallbacks;
+ Subscriptions<UserPtr> m_onDelCallbacks;
};
}
AUTH_AO::AUTH_AO()
: users(NULL),
isRunning(false),
- onAddUserNotifier(*this),
- onDelUserNotifier(*this),
logger(STG::PluginLogger::get("auth_ao"))
{
}
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); });
if (!isRunning)
return 0;
-users->DelNotifierUserAdd(&onAddUserNotifier);
-users->DelNotifierUserDel(&onDelUserNotifier);
+m_onAddUserConn.disconnect();
+m_onDelUserConn.disconnect();
auto it = userList.begin();
while (it != userList.end())
#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"
std::list<CHG_BEFORE_NOTIFIER<STG::UserIPs> > BeforeChgIPNotifierList;
std::list<CHG_AFTER_NOTIFIER<STG::UserIPs> > AfterChgIPNotifierList;
- class ADD_USER_NONIFIER: public STG::NotifierBase<UserPtr> {
- 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<UserPtr> {
- 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;
stgSettings(NULL),
listenSocket(-1),
enabledDirs(0xFFffFFff),
- onDelUserNotifier(*this),
logger(STG::PluginLogger::get("auth_ia"))
{
InitContext("pr7Hhen", 7, &ctxS);
//-----------------------------------------------------------------------------
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)); });
}
}
-users->DelNotifierUserDel(&onDelUserNotifier);
+m_onDelUserConn.disconnect();
if (isRunningRun)
m_thread.detach();
class AUTH_IA;
using UserPtr = STG::User*;
//-----------------------------------------------------------------------------
-class DEL_USER_NOTIFIER: public STG::NotifierBase<UserPtr> {
-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;
uint32_t enabledDirs;
- DEL_USER_NOTIFIER onDelUserNotifier;
+ STG::ScopedConnection m_onDelUserConn;
STG::PluginLogger logger;
AUTH_IA * auth;
};
-//-----------------------------------------------------------------------------
-inline
-void DEL_USER_NOTIFIER::notify(const UserPtr & user)
-{
- auth.DelUser(user);
-}
PING::PING()
: users(nullptr),
isRunning(false),
- onAddUserNotifier(*this),
- onDelUserNotifier(*this),
logger(STG::PluginLogger::get("ping"))
{
}
{
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();
nanosleep(&ts, nullptr);
}
-users->DelNotifierUserAdd(&onAddUserNotifier);
-users->DelNotifierUserDel(&onDelUserNotifier);
+m_onAddUserConn.disconnect();
+m_onDelUserConn.disconnect();
std::list<UserPtr>::iterator users_iter;
users_iter = usersList.begin();
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);
-}
-//-----------------------------------------------------------------------------
#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"
const PING & ping;
};
//-----------------------------------------------------------------------------
-class ADD_USER_NONIFIER_PING: public STG::NotifierBase<UserPtr> {
-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<UserPtr> {
-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) {}
std::list<CHG_CURRIP_NOTIFIER_PING> ChgCurrIPNotifierList;
std::list<CHG_IPS_NOTIFIER_PING> ChgIPNotifierList;
- ADD_USER_NONIFIER_PING onAddUserNotifier;
- DEL_USER_NONIFIER_PING onDelUserNotifier;
+ STG::ScopedConnection m_onAddUserConn;
+ STG::ScopedConnection m_onDelUserConn;
STG::PluginLogger logger;
};
isRunning(false),
users(nullptr),
sock(0),
- onAddUserNotifier(*this),
- onDelUserNotifier(*this),
logger(STG::PluginLogger::get("rscript"))
{
}
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;
}
}
-users->DelNotifierUserDel(&onDelUserNotifier);
-users->DelNotifierUserAdd(&onAddUserNotifier);
-
if (isRunning)
{
logger("Cannot stop thread.");
#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"
using UserPtr = STG::User*;
-//-----------------------------------------------------------------------------
-class ADD_USER_NONIFIER: public STG::NotifierBase<UserPtr> {
-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<UserPtr> {
-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<uint32_t> {
public:
int sock;
- ADD_USER_NONIFIER onAddUserNotifier;
- DEL_USER_NONIFIER onDelUserNotifier;
+ STG::ScopedConnection m_onAddUserConn;
+ STG::ScopedConnection m_onDelUserConn;
STG::PluginLogger logger;
REMOTE_SCRIPT & rscript;
};
//-----------------------------------------------------------------------------
-inline void ADD_USER_NONIFIER::notify(const UserPtr & user)
-{
-rs.AddUser(user);
-}
-//-----------------------------------------------------------------------------
-inline void DEL_USER_NONIFIER::notify(const UserPtr & user)
-{
-rs.DelUser(user);
-}
-//-----------------------------------------------------------------------------
} // namespace RS
lastReconnectTry(0),
reconnectTimeout(1),
sock(-1),
- addUserNotifier(*this),
- delUserNotifier(*this),
addDelTariffNotifier(*this),
logger(STG::PluginLogger::get("smux"))
{
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);
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())
-#ifndef __SMUX_H__
-#define __SMUX_H__
+#pragma once
-#include <string>
-#include <map>
-#include <list>
-#include <mutex>
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
-#include <jthread.hpp>
-#pragma GCC diagnostic pop
-#include <cstdint>
+#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 <string>
+#include <map>
+#include <list>
+#include <mutex>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#include <jthread.hpp>
+#pragma GCC diagnostic pop
+#include <cstdint>
namespace STG
{
: STG::NotifierBase<STG::TariffData>(), smux(s) {}
void notify(const STG::TariffData &) override;
-private:
- SMUX & smux;
-};
-//-----------------------------------------------------------------------------
-class ADD_USER_NOTIFIER : public STG::NotifierBase<UserPtr> {
-public:
- explicit ADD_USER_NOTIFIER(SMUX & s) : STG::NotifierBase<STG::User*>(), smux(s) {}
- void notify(const UserPtr &) override;
-
-private:
- SMUX & smux;
-};
-//-----------------------------------------------------------------------------
-class DEL_USER_NOTIFIER : public STG::NotifierBase<UserPtr> {
-public:
- explicit DEL_USER_NOTIFIER(SMUX & s) : STG::NotifierBase<UserPtr>(), smux(s) {}
- void notify(const UserPtr &) override;
-
private:
SMUX & smux;
};
Sensors sensors;
Tables tables;
+ STG::ScopedConnection m_onAddUserConn;
+ STG::ScopedConnection m_onDelUserConn;
+
std::list<CHG_AFTER_NOTIFIER> notifiers;
- ADD_USER_NOTIFIER addUserNotifier;
- DEL_USER_NOTIFIER delUserNotifier;
ADD_DEL_TARIFF_NOTIFIER addDelTariffNotifier;
STG::PluginLogger logger;
{
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
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;
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()
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()); });
-}
-//-----------------------------------------------------------------------------
#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"
using UserImplPtr = UserImpl*;
//-----------------------------------------------------------------------------
-class ADD_USER_NONIFIER: public NotifierBase<UserImplPtr> {
-public:
- explicit ADD_USER_NONIFIER(TraffCounterImpl & t) :
- NotifierBase<UserImplPtr>(),
- 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<UserImplPtr> {
-public:
- explicit DEL_USER_NONIFIER(TraffCounterImpl & t) :
- NotifierBase<UserImplPtr>(),
- 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:
std::mutex m_mutex;
std::jthread m_thread;
+ ScopedConnection m_onAddUserConn;
+ ScopedConnection m_onDelUserConn;
+
std::list<TRF_IP_BEFORE> ipBeforeNotifiers;
std::list<TRF_IP_AFTER> ipAfterNotifiers;
-
- ADD_USER_NONIFIER addUserNotifier;
- DEL_USER_NONIFIER delUserNotifier;
};
}
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;
}
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<std::mutex> lock(m_mutex);
return false;
}
//-----------------------------------------------------------------------------
-void UsersImpl::AddNotifierUserAdd(NotifierBase<UserPtr> * n)
-{
-std::lock_guard<std::mutex> lock(m_mutex);
-onAddNotifiers.insert(n);
-}
-//-----------------------------------------------------------------------------
-void UsersImpl::DelNotifierUserAdd(NotifierBase<UserPtr> * n)
-{
-std::lock_guard<std::mutex> lock(m_mutex);
-onAddNotifiers.erase(n);
-}
-//-----------------------------------------------------------------------------
-void UsersImpl::AddNotifierUserDel(NotifierBase<UserPtr> * n)
-{
-std::lock_guard<std::mutex> lock(m_mutex);
-onDelNotifiers.insert(n);
-}
-//-----------------------------------------------------------------------------
-void UsersImpl::DelNotifierUserDel(NotifierBase<UserPtr> * n)
-{
-std::lock_guard<std::mutex> lock(m_mutex);
-onDelNotifiers.erase(n);
-}
-//-----------------------------------------------------------------------------
-void UsersImpl::AddNotifierUserAdd(NotifierBase<UserImplPtr> * n)
-{
-std::lock_guard<std::mutex> lock(m_mutex);
-onAddNotifiersImpl.insert(n);
-}
-//-----------------------------------------------------------------------------
-void UsersImpl::DelNotifierUserAdd(NotifierBase<UserImplPtr> * n)
-{
-std::lock_guard<std::mutex> lock(m_mutex);
-onAddNotifiersImpl.erase(n);
-}
-//-----------------------------------------------------------------------------
-void UsersImpl::AddNotifierUserDel(NotifierBase<UserImplPtr> * n)
-{
-std::lock_guard<std::mutex> lock(m_mutex);
-onDelNotifiersImpl.insert(n);
-}
-//-----------------------------------------------------------------------------
-void UsersImpl::DelNotifierUserDel(NotifierBase<UserImplPtr> * n)
-{
-std::lock_guard<std::mutex> lock(m_mutex);
-onDelNotifiersImpl.erase(n);
-}
-//-----------------------------------------------------------------------------
unsigned int UsersImpl::OpenSearch()
{
std::lock_guard<std::mutex> lock(m_mutex);
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<UserPtr> *) override;
- void DelNotifierUserAdd(NotifierBase<UserPtr> *) override;
+ UsersImpl(SettingsImpl * s, Store * store,
+ Tariffs * tariffs, Services & svcs,
+ const Admin& sysAdmin);
- void AddNotifierUserDel(NotifierBase<UserPtr> *) override;
- void DelNotifierUserDel(NotifierBase<UserPtr> *) 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<UserImplPtr> *);
- void DelNotifierUserAdd(NotifierBase<UserImplPtr> *);
+ bool TariffInUse(const std::string & tariffName) const override;
- void AddNotifierUserDel(NotifierBase<UserImplPtr> *);
- void DelNotifierUserDel(NotifierBase<UserImplPtr> *);
+ template <typename F>
+ auto onUserImplAdd(F&& f) { return m_onAddImplCallbacks.add(std::forward<F>(f)); }
+ template <typename F>
+ auto onUserImplDel(F&& f) { return m_onDelImplCallbacks.add(std::forward<F>(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<UserImpl> users;
- std::list<USER_TO_DEL> usersToDelete;
+ std::list<UserImpl> users;
+ std::list<USER_TO_DEL> usersToDelete;
- std::map<uint32_t, user_iter> ipIndex;
- std::map<std::string, user_iter> loginIndex;
+ std::map<uint32_t, user_iter> ipIndex;
+ std::map<std::string, user_iter> 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<unsigned int, user_iter> searchDescriptors;
+ mutable std::map<unsigned int, user_iter> searchDescriptors;
- std::set<NotifierBase<UserPtr>*> onAddNotifiers;
- std::set<NotifierBase<UserPtr>*> onDelNotifiers;
- std::set<NotifierBase<UserImplPtr>*> onAddNotifiersImpl;
- std::set<NotifierBase<UserImplPtr>*> onDelNotifiersImpl;
+ Subscriptions<UserImplPtr> m_onAddImplCallbacks;
+ Subscriptions<UserImplPtr> m_onDelImplCallbacks;
};
}
#include <boost/test/unit_test.hpp>
#pragma GCC diagnostic pop
+using STG::Subscriptions;
+using STG::ScopedConnection;
+
namespace
{
}
-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<uint8_t> unary;
+ Subscriptions<uint8_t> unary;
BOOST_CHECK(unary.empty());
BOOST_CHECK_EQUAL(unary.size(), 0);
- STG::Subscriptions<uint8_t, std::string> binary;
+ Subscriptions<uint8_t, std::string> binary;
BOOST_CHECK(binary.empty());
BOOST_CHECK_EQUAL(binary.size(), 0);
}
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);
BOOST_CHECK(nullary.empty());
BOOST_CHECK_EQUAL(nullary.size(), 0);
- STG::Subscriptions<uint8_t> unary;
+ Subscriptions<uint8_t> 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);
BOOST_CHECK(unary.empty());
BOOST_CHECK_EQUAL(unary.size(), 0);
- STG::Subscriptions<uint8_t, std::string> binary;
+ Subscriptions<uint8_t, std::string> 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);
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();
BOOST_CHECK_EQUAL(r.value1R2, 0);
BOOST_CHECK_EQUAL(r.value2R2, "");
- STG::Subscriptions<uint8_t> unary;
+ Subscriptions<uint8_t> 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);
BOOST_CHECK_EQUAL(r.value1R2, 0);
BOOST_CHECK_EQUAL(r.value2R2, "");
- STG::Subscriptions<uint8_t, std::string> binary;
+ Subscriptions<uint8_t, std::string> 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");
bool TariffInUse(const std::string& /*tariffName*/) const override
{ return -1; }
- void AddNotifierUserAdd(STG::NotifierBase<UserPtr>* /*notifier*/) override {}
- void DelNotifierUserAdd(STG::NotifierBase<UserPtr>* /*notifier*/) override {}
-
- void AddNotifierUserDel(STG::NotifierBase<UserPtr>* /*notifier*/) override {}
- void DelNotifierUserDel(STG::NotifierBase<UserPtr>* /*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 {}