]> git.stg.codes - stg.git/blobdiff - projects/stargazer/user_impl.cpp
Use std::lock_guard instead of STG_LOCKER.
[stg.git] / projects / stargazer / user_impl.cpp
index 60e801b98144c58c2fe3275cc9429a855d9f87f0..af94d47743132751ca44c8d21d9ba5077a69561c 100644 (file)
@@ -88,10 +88,6 @@ UserImpl::UserImpl(const Settings * s,
       WriteServLog(Logger::get()),
       lastScanMessages(0),
       id(0),
-      __connected(0),
-      connected(__connected),
-      __currIP(0),
-      currIP(__currIP),
       lastIPForDisconnect(0),
       pingTime(0),
       sysAdmin(a),
@@ -139,14 +135,9 @@ UserImpl::UserImpl(const Settings * s,
       userdata8(properties.userdata8),
       userdata9(properties.userdata9),
       sessionUploadModTime(stgTime),
-      sessionDownloadModTime(stgTime),
-      passiveNotifier(this),
-      disabledNotifier(this),
-      tariffNotifier(this),
-      cashNotifier(this),
-      ipNotifier(this)
+      sessionDownloadModTime(stgTime)
 {
-Init();
+    Init();
 }
 //-----------------------------------------------------------------------------
 void UserImpl::Init()
@@ -158,16 +149,11 @@ ips = UserIPs::parse("*");
 lastWriteStat = stgTime + random() % settings->GetStatWritePeriod();
 lastWriteDetailedStat = stgTime;
 
-properties.tariffName.AddBeforeNotifier(&tariffNotifier);
-properties.passive.AddBeforeNotifier(&passiveNotifier);
-properties.disabled.AddAfterNotifier(&disabledNotifier);
-properties.cash.AddBeforeNotifier(&cashNotifier);
-ips.AddAfterNotifier(&ipNotifier);
-
-pthread_mutexattr_t attr;
-pthread_mutexattr_init(&attr);
-pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-pthread_mutex_init(&mutex, &attr);
+m_beforePassiveConn = properties.passive.beforeChange([this](auto oldVal, auto newVal){ onPassiveChange(oldVal, newVal); });
+m_afterDisabledConn = properties.disabled.afterChange([this](auto oldVal, auto newVal){ onDisabledChange(oldVal, newVal); });
+m_beforeTariffConn = properties.tariffName.beforeChange([this](const auto& oldVal, const auto& newVal){ onTariffChange(oldVal, newVal); });
+m_beforeCashConn = properties.cash.beforeChange([this](auto oldVal, auto newVal){ onCashChange(oldVal, newVal); });
+m_afterIPConn = ips.afterChange([this](const auto& oldVal, const auto& newVal){ onIPChange(oldVal, newVal); });
 }
 //-----------------------------------------------------------------------------
 UserImpl::UserImpl(const UserImpl & u)
@@ -177,10 +163,6 @@ UserImpl::UserImpl(const UserImpl & u)
       lastScanMessages(0),
       login(u.login),
       id(u.id),
-      __connected(0),
-      connected(__connected),
-      __currIP(u.__currIP),
-      currIP(__currIP),
       lastIPForDisconnect(0),
       pingTime(u.pingTime),
       sysAdmin(u.sysAdmin),
@@ -233,42 +215,23 @@ UserImpl::UserImpl(const UserImpl & u)
       sessionUpload(),
       sessionDownload(),
       sessionUploadModTime(stgTime),
-      sessionDownloadModTime(stgTime),
-      passiveNotifier(this),
-      disabledNotifier(this),
-      tariffNotifier(this),
-      cashNotifier(this),
-      ipNotifier(this)
+      sessionDownloadModTime(stgTime)
 {
-if (&u == this)
-    return;
-
-properties.tariffName.AddBeforeNotifier(&tariffNotifier);
-properties.passive.AddBeforeNotifier(&passiveNotifier);
-properties.disabled.AddAfterNotifier(&disabledNotifier);
-properties.cash.AddBeforeNotifier(&cashNotifier);
-ips.AddAfterNotifier(&ipNotifier);
+    if (&u == this)
+        return;
 
-properties.SetProperties(u.properties);
+    m_beforePassiveConn = properties.passive.beforeChange([this](auto oldVal, auto newVal){ onPassiveChange(oldVal, newVal); });
+    m_afterDisabledConn = properties.disabled.afterChange([this](auto oldVal, auto newVal){ onDisabledChange(oldVal, newVal); });
+    m_beforeTariffConn = properties.tariffName.beforeChange([this](const auto& oldVal, const auto& newVal){ onTariffChange(oldVal, newVal); });
+    m_beforeCashConn = properties.cash.beforeChange([this](auto oldVal, auto newVal){ onCashChange(oldVal, newVal); });
+    m_afterIPConn = ips.afterChange([this](const auto& oldVal, const auto& newVal){ onIPChange(oldVal, newVal); });
 
-pthread_mutexattr_t attr;
-pthread_mutexattr_init(&attr);
-pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-pthread_mutex_init(&mutex, &attr);
-}
-//-----------------------------------------------------------------------------
-UserImpl::~UserImpl()
-{
-properties.tariffName.DelBeforeNotifier(&tariffNotifier);
-properties.passive.DelBeforeNotifier(&passiveNotifier);
-properties.disabled.DelAfterNotifier(&disabledNotifier);
-properties.cash.DelBeforeNotifier(&cashNotifier);
-pthread_mutex_destroy(&mutex);
+    properties.SetProperties(u.properties);
 }
 //-----------------------------------------------------------------------------
 void UserImpl::SetLogin(const std::string & l)
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 static int idGen = 0;
 assert(login.empty() && "Login is already set");
 login = l;
@@ -277,7 +240,7 @@ id = idGen++;
 //-----------------------------------------------------------------------------
 int UserImpl::ReadConf()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 UserConf conf;
 
 if (store->RestoreUserConf(&conf, login))
@@ -325,7 +288,7 @@ return 0;
 //-----------------------------------------------------------------------------
 int UserImpl::ReadStat()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 UserStat stat;
 
 if (store->RestoreUserStat(&stat, login))
@@ -344,7 +307,7 @@ return 0;
 //-----------------------------------------------------------------------------
 int UserImpl::WriteConf()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 UserConf conf(properties.GetConf());
 
 printfd(__FILE__, "UserImpl::WriteConf()\n");
@@ -363,7 +326,7 @@ return 0;
 //-----------------------------------------------------------------------------
 int UserImpl::WriteStat()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 UserStat stat(properties.GetStat());
 
 if (store->SaveUserStat(stat, login))
@@ -382,7 +345,7 @@ return 0;
 //-----------------------------------------------------------------------------
 int UserImpl::WriteMonthStat()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 time_t tt = stgTime - 3600;
 struct tm t1;
 localtime_r(&tt, &t1);
@@ -402,7 +365,7 @@ return 0;
 //-----------------------------------------------------------------------------
 int UserImpl::Authorize(uint32_t ip, uint32_t dirs, const Auth * auth)
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 /*
  *  Authorize user. It only means that user will be authorized. Nothing more.
  *  User can be connected or disconnected while authorized.
@@ -428,7 +391,7 @@ dirsFromBits(enabledDirs, dirs);
 
 if (!authorizedBy.empty())
     {
-    if (currIP != ip)
+    if (m_currIP != ip)
         {
         // We are already authorized, but with different IP address
         errorStr = "User " + login + " already authorized with IP address " + inet_ntostring(ip);
@@ -458,8 +421,8 @@ else
 
     if (ips.ConstData().find(ip))
         {
-        currIP = ip;
-        lastIPForDisconnect = currIP;
+        m_currIP = ip;
+        lastIPForDisconnect = m_currIP;
         }
     else
         {
@@ -480,7 +443,7 @@ return 0;
 //-----------------------------------------------------------------------------
 void UserImpl::Unauthorize(const Auth * auth, const std::string & reason)
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 /*
  *  Authorizer tries to unauthorize user, that was not authorized by it
  */
@@ -492,9 +455,9 @@ authorizedModificationTime = stgTime;
 if (authorizedBy.empty())
     {
     lastDisconnectReason = reason;
-    lastIPForDisconnect = currIP;
-    currIP = 0; // DelUser in traffcounter
-    if (connected)
+    lastIPForDisconnect = m_currIP;
+    m_currIP = 0; // DelUser in traffcounter
+    if (m_connected)
         Disconnect(false, "not authorized");
     return;
     }
@@ -502,14 +465,14 @@ if (authorizedBy.empty())
 //-----------------------------------------------------------------------------
 bool UserImpl::IsAuthorizedBy(const Auth * auth) const
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 // Is this user authorized by specified authorizer?
 return authorizedBy.find(auth) != authorizedBy.end();
 }
 //-----------------------------------------------------------------------------
 std::vector<std::string> UserImpl::GetAuthorizers() const
 {
-    STG_LOCKER lock(&mutex);
+    std::lock_guard lock(m_mutex);
     std::vector<std::string> list;
     std::transform(authorizedBy.begin(), authorizedBy.end(), std::back_inserter(list), [](const auto auth){ return auth->GetVersion(); });
     return list;
@@ -521,8 +484,6 @@ void UserImpl::Connect(bool fakeConnect)
  * Connect user to Internet. This function is differ from Authorize() !!!
  */
 
-STG_LOCKER lock(&mutex);
-
 if (!fakeConnect)
     {
     std::string scriptOnConnect = settings->GetScriptsDir() + "/OnConnect";
@@ -536,7 +497,7 @@ if (!fakeConnect)
                   "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
                   scriptOnConnect.c_str(),
                   login.c_str(),
-                  inet_ntostring(currIP).c_str(),
+                  inet_ntostring(m_currIP).c_str(),
                   cash.ConstData(),
                   id,
                   dirs.c_str());
@@ -555,17 +516,17 @@ if (!fakeConnect)
         WriteServLog("Script %s cannot be executed. File not found.", scriptOnConnect.c_str());
         }
 
-    connected = true;
+    m_connected = true;
     }
 
-if (!settings->GetDisableSessionLog() && store->WriteUserConnect(login, currIP))
+if (!settings->GetDisableSessionLog() && store->WriteUserConnect(login, m_currIP))
     {
     WriteServLog("Cannot write connect for user %s.", login.c_str());
     WriteServLog("%s", store->GetStrError().c_str());
     }
 
 if (!fakeConnect)
-    lastIPForDisconnect = currIP;
+    lastIPForDisconnect = m_currIP;
 }
 //-----------------------------------------------------------------------------
 void UserImpl::Disconnect(bool fakeDisconnect, const std::string & reason)
@@ -574,8 +535,6 @@ void UserImpl::Disconnect(bool fakeDisconnect, const std::string & reason)
  *  Disconnect user from Internet. This function is differ from UnAuthorize() !!!
  */
 
-STG_LOCKER lock(&mutex);
-
 if (!lastIPForDisconnect)
     {
     printfd(__FILE__, "lastIPForDisconnect\n");
@@ -615,7 +574,7 @@ if (!fakeDisconnect)
         WriteServLog("Script OnDisconnect cannot be executed. File not found.");
         }
 
-    connected = false;
+    m_connected = false;
     }
 
 std::string reasonMessage(reason);
@@ -640,7 +599,7 @@ sessionDownloadModTime = stgTime;
 //-----------------------------------------------------------------------------
 void UserImpl::Run()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 
 if (stgTime > lastWriteStat + settings->GetStatWritePeriod())
     {
@@ -665,13 +624,13 @@ if (passive.ConstData()
 
 if (!authorizedBy.empty())
     {
-    if (connected)
+    if (m_connected)
         properties.Stat().lastActivityTime = stgTime;
 
-    if (!connected && IsInetable())
+    if (!m_connected && IsInetable())
         Connect();
 
-    if (connected && !IsInetable())
+    if (m_connected && !IsInetable())
         {
         if (disabled)
             Disconnect(false, "disabled");
@@ -689,7 +648,7 @@ if (!authorizedBy.empty())
     }
 else
     {
-    if (connected)
+    if (m_connected)
         Disconnect(false, "not authorized");
     }
 
@@ -697,7 +656,7 @@ else
 //-----------------------------------------------------------------------------
 void UserImpl::UpdatePingTime(time_t t)
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 if (t)
     pingTime = t;
 else
@@ -732,9 +691,9 @@ void UserImpl::AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len)
 void UserImpl::AddTraffStatU(int dir, uint32_t ip, uint32_t len)
 #endif
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 
-if (!connected || tariff == NULL)
+if (!m_connected || tariff == NULL)
     return;
 
 double cost = 0;
@@ -825,9 +784,9 @@ void UserImpl::AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len)
 void UserImpl::AddTraffStatD(int dir, uint32_t ip, uint32_t len)
 #endif
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 
-if (!connected || tariff == NULL)
+if (!m_connected || tariff == NULL)
     return;
 
 double cost = 0;
@@ -911,57 +870,9 @@ else
     }
 }
 //-----------------------------------------------------------------------------
-void UserImpl::AddCurrIPBeforeNotifier(CURR_IP_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-currIP.AddBeforeNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::DelCurrIPBeforeNotifier(const CURR_IP_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-currIP.DelBeforeNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::AddCurrIPAfterNotifier(CURR_IP_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-currIP.AddAfterNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::DelCurrIPAfterNotifier(const CURR_IP_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-currIP.DelAfterNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::AddConnectedBeforeNotifier(CONNECTED_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-connected.AddBeforeNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::DelConnectedBeforeNotifier(const CONNECTED_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-connected.DelBeforeNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::AddConnectedAfterNotifier(CONNECTED_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-connected.AddAfterNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::DelConnectedAfterNotifier(const CONNECTED_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-connected.DelAfterNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
 void UserImpl::OnAdd()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 
 std::string scriptOnAdd = settings->GetScriptsDir() + "/OnUserAdd";
 
@@ -979,7 +890,7 @@ else
 //-----------------------------------------------------------------------------
 void UserImpl::OnDelete()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 
 std::string scriptOnDel = settings->GetScriptsDir() + "/OnUserDel";
 
@@ -1016,7 +927,7 @@ if (!traffStatSaved.second.empty())
 TraffStat ts;
 
     {
-    STG_LOCKER lock(&mutex);
+    std::lock_guard lock(m_mutex);
     ts.swap(traffStat);
     }
 
@@ -1032,7 +943,7 @@ if (ts.size() && !disabledDetailStat)
         if (!hard)
             {
             printfd(__FILE__, "UserImpl::WriteDetailStat() - pushing detail stat to queue\n");
-            STG_LOCKER lock(&mutex);
+            std::lock_guard lock(m_mutex);
             traffStatSaved.second.swap(ts);
             traffStatSaved.first = lastWriteDetailedStat;
             }
@@ -1045,8 +956,12 @@ return 0;
 //-----------------------------------------------------------------------------
 double UserImpl::GetPassiveTimePart() const
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
+return getPassiveTimePart();
+}
 
+double UserImpl::getPassiveTimePart() const
+{
 static const std::array<unsigned, 12> daysInMonth{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
 struct tm tms;
@@ -1071,7 +986,7 @@ return static_cast<double>(dt) / secMonth;
 //-----------------------------------------------------------------------------
 void UserImpl::SetPassiveTimeAsNewUser()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 
 time_t t = stgTime;
 struct tm tm;
@@ -1085,9 +1000,9 @@ passiveTime = static_cast<time_t>(pt * 24 * 3600 * daysCurrMon);
 //-----------------------------------------------------------------------------
 void UserImpl::MidnightResetSessionStat()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 
-if (connected)
+if (m_connected)
     {
     Disconnect(true, "fake");
     Connect(true);
@@ -1096,9 +1011,9 @@ if (connected)
 //-----------------------------------------------------------------------------
 void UserImpl::ProcessNewMonth()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 //  Reset traff
-if (connected)
+if (m_connected)
     Disconnect(true, "fake");
 
 WriteMonthStat();
@@ -1106,7 +1021,7 @@ WriteMonthStat();
 properties.Stat().monthUp.reset();
 properties.Stat().monthDown.reset();
 
-if (connected)
+if (m_connected)
     Connect(true);
 
 //  Set new tariff
@@ -1139,7 +1054,7 @@ if (nextTariff.ConstData() != "")
 //-----------------------------------------------------------------------------
 void UserImpl::ProcessDayFeeSpread()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 
 if (passive.ConstData() || tariff == NULL)
     return;
@@ -1176,7 +1091,7 @@ ResetPassiveTime();
 //-----------------------------------------------------------------------------
 void UserImpl::ProcessDayFee()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 
 if (tariff == NULL)
     return;
@@ -1187,7 +1102,7 @@ if (tariff->GetPeriod() != Tariff::MONTH)
 double passiveTimePart = 1.0;
 if (!settings->GetFullFee())
     {
-    passiveTimePart = GetPassiveTimePart();
+    passiveTimePart = getPassiveTimePart();
     }
 else
     {
@@ -1247,7 +1162,7 @@ switch (settings->GetFeeChargeType())
 //-----------------------------------------------------------------------------
 void UserImpl::ProcessDailyFee()
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 
 if (passive.ConstData() || tariff == NULL)
     return;
@@ -1284,10 +1199,12 @@ struct tm tms;
 time_t t = stgTime;
 localtime_r(&t, &tms);
 
+std::lock_guard lock(m_mutex);
+
 double passiveTimePart = 1.0;
 if (!settings->GetFullFee())
     {
-    passiveTimePart = GetPassiveTimePart();
+    passiveTimePart = getPassiveTimePart();
     }
 else
     {
@@ -1355,7 +1272,7 @@ if (tariff != NULL)
 //-----------------------------------------------------------------------------
 int UserImpl::AddMessage(Message * msg)
 {
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
 
 if (SendMessage(*msg))
     {
@@ -1399,7 +1316,7 @@ int ret = -1;
 std::set<const Auth*>::iterator it(authorizedBy.begin());
 while (it != authorizedBy.end())
     {
-    if (!(*it++)->SendMessage(msg, currIP))
+    if (!(*it++)->SendMessage(msg, m_currIP))
         ret = 0;
     }
 if (!ret)
@@ -1479,7 +1396,7 @@ std::string UserImpl::GetParamValue(const std::string & name) const
         return stream.str();
         }
     if (lowerName == "login")       return login;
-    if (lowerName == "currip")      return currIP.ToString();
+    if (lowerName == "currip")      return m_currIP.ToString();
     if (lowerName == "enableddirs") return GetEnabledDirs();
     if (lowerName == "tariff")      return properties.tariffName;
     if (properties.Exists(lowerName))
@@ -1493,51 +1410,55 @@ std::string UserImpl::GetParamValue(const std::string & name) const
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-void STG::CHG_PASSIVE_NOTIFIER::notify(const int & oldPassive, const int & newPassive)
+void UserImpl::onPassiveChange(int oldVal, int newVal)
 {
-if (newPassive && !oldPassive && user->tariff != NULL)
-    user->properties.cash.Set(user->cash - user->tariff->GetPassiveCost(),
-                            *user->sysAdmin,
-                            user->login,
-                            *user->store,
+    std::lock_guard lock(m_mutex);
+    if (newVal && !oldVal && tariff != NULL)
+        properties.cash.Set(cash - tariff->GetPassiveCost(),
+                            *sysAdmin,
+                            login,
+                            *store,
                             "Freeze");
 }
 //-----------------------------------------------------------------------------
-void STG::CHG_DISABLED_NOTIFIER::notify(const int & oldValue, const int & newValue)
+void UserImpl::onDisabledChange(int oldVal, int newVal)
 {
-if (oldValue && !newValue && user->GetConnected())
-    user->Disconnect(false, "disabled");
-else if (!oldValue && newValue && user->IsInetable())
-    user->Connect(false);
+    std::lock_guard lock(m_mutex);
+    if (oldVal && !newVal && GetConnected())
+        Disconnect(false, "disabled");
+    else if (!oldVal && newVal && IsInetable())
+        Connect(false);
 }
 //-----------------------------------------------------------------------------
-void STG::CHG_TARIFF_NOTIFIER::notify(const std::string &, const std::string & newTariff)
+void UserImpl::onTariffChange(const std::string& /*oldVal*/, const std::string& newVal)
 {
-STG_LOCKER lock(&user->mutex);
-if (user->settings->GetReconnectOnTariffChange() && user->connected)
-    user->Disconnect(false, "Change tariff");
-user->tariff = user->tariffs->FindByName(newTariff);
-if (user->settings->GetReconnectOnTariffChange() &&
-    !user->authorizedBy.empty() &&
-    user->IsInetable())
+    std::lock_guard lock(m_mutex);
+    if (settings->GetReconnectOnTariffChange() && m_connected)
+        Disconnect(false, "Change tariff");
+    tariff = tariffs->FindByName(newVal);
+    if (settings->GetReconnectOnTariffChange() &&
+        !authorizedBy.empty() &&
+        IsInetable())
     {
-    // This notifier gets called *before* changing the tariff, and in Connect we want to see new tariff name.
-    user->properties.Conf().tariffName = newTariff;
-    user->Connect(false);
+        // This notifier gets called *before* changing the tariff, and in Connect we want to see new tariff name.
+        properties.Conf().tariffName = newVal;
+        Connect(false);
     }
 }
 //-----------------------------------------------------------------------------
-void STG::CHG_CASH_NOTIFIER::notify(const double & oldCash, const double & newCash)
+void UserImpl::onCashChange(double oldVal, double newVal)
 {
-user->lastCashAddTime = *const_cast<time_t *>(&stgTime);
-user->lastCashAdd = newCash - oldCash;
+    time_t now = stgTime;
+    lastCashAddTime = now;
+    lastCashAdd = newVal - oldVal;
 }
 //-----------------------------------------------------------------------------
-void STG::CHG_IPS_NOTIFIER::notify(const UserIPs & from, const UserIPs & to)
+void UserImpl::onIPChange(const UserIPs& oldVal, const UserIPs& newVal)
 {
-printfd(__FILE__, "Change IP from '%s' to '%s'\n", from.toString().c_str(), to.toString().c_str());
-if (user->connected)
-    user->Disconnect(false, "Change IP");
-if (!user->authorizedBy.empty() && user->IsInetable())
-    user->Connect(false);
+    std::lock_guard lock(m_mutex);
+    printfd(__FILE__, "Change IP from '%s' to '%s'\n", oldVal.toString().c_str(), newVal.toString().c_str());
+    if (m_connected)
+        Disconnect(false, "Change IP");
+    if (!authorizedBy.empty() && IsInetable())
+        Connect(false);
 }