From 6bde0fc270dd1a7a66b56b389524de523c333807 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 8 Mar 2016 13:52:51 -0500 Subject: [PATCH 1/2] Add config write delay setting --- include/znc/znc.h | 8 ++++++++ src/znc.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/include/znc/znc.h b/include/znc/znc.h index e57cdb23..ff31291d 100644 --- a/include/znc/znc.h +++ b/include/znc/znc.h @@ -31,6 +31,7 @@ class CListener; class CUser; class CIRCNetwork; class CConnectQueueTimer; +class CConfigWriteTimer; class CConfig; class CFile; @@ -47,6 +48,7 @@ class CZNC { ECONFIG_NEED_REHASH, ECONFIG_NEED_WRITE, ECONFIG_NEED_VERBOSE_WRITE, + ECONFIG_DELAYED_WRITE, ECONFIG_NEED_QUIT, // Not really config... }; @@ -125,6 +127,7 @@ class CZNC { void SetSSLCiphers(const CString& sCiphers) { m_sSSLCiphers = sCiphers; } bool SetSSLProtocols(const CString& sProtocols); void SetSSLCertFile(const CString& sFile) { m_sSSLCertFile = sFile; } + void SetConfigWriteDelay(unsigned int i) { m_uiConfigWriteDelay = i; } // !Setters // Getters @@ -170,6 +173,7 @@ class CZNC { } CString GetSSLCertFile() const { return m_sSSLCertFile; } static VCString GetAvailableSSLProtocols(); + unsigned int GetConfigWriteDelay() const { return m_uiConfigWriteDelay; } // !Getters // Static allocator @@ -242,6 +246,8 @@ class CZNC { // Never call this unless you are CConnectQueueTimer::~CConnectQueueTimer() void LeakConnectQueueTimer(CConnectQueueTimer* pTimer); + void DisableConfigTimer(); + static void DumpConfig(const CConfig* Config); private: @@ -300,6 +306,8 @@ class CZNC { bool m_bProtectWebSessions; bool m_bHideVersion; CTranslationDomainRefHolder m_Translation; + unsigned int m_uiConfigWriteDelay; + CConfigWriteTimer* m_pConfigTimer; }; #endif // !ZNC_H diff --git a/src/znc.cpp b/src/znc.cpp index 7e0998c2..ab103fff 100644 --- a/src/znc.cpp +++ b/src/znc.cpp @@ -76,7 +76,9 @@ CZNC::CZNC() m_sConnectThrottle(), m_bProtectWebSessions(true), m_bHideVersion(false), - m_Translation("znc") { + m_Translation("znc"), + m_uiConfigWriteDelay(0), + m_pConfigTimer(nullptr) { if (!InitCsocket()) { CUtils::PrintError("Could not initialize Csocket!"); exit(-1); @@ -210,6 +212,21 @@ bool CZNC::HandleUserDeletion() { return true; } +class CConfigWriteTimer : public CCron { + public: + CConfigWriteTimer(int iSecs) : CCron() { + SetName("Config write timer"); + Start(iSecs); + } + + protected: + void RunJob() override { + CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_WRITE); + + CZNC::Get().DisableConfigTimer(); + } +}; + void CZNC::Loop() { while (true) { CString sError; @@ -227,10 +244,24 @@ void CZNC::Loop() { true); } break; + case ECONFIG_DELAYED_WRITE: + SetConfigState(ECONFIG_NOTHING); + + if (GetConfigWriteDelay() > 0) { + if (m_pConfigTimer == nullptr) { + m_pConfigTimer = new CConfigWriteTimer(GetConfigWriteDelay()); + GetManager().AddCron(m_pConfigTimer); + } + break; + } + /* Fall through */ case ECONFIG_NEED_WRITE: case ECONFIG_NEED_VERBOSE_WRITE: SetConfigState(ECONFIG_NOTHING); + // stop pending configuration timer + DisableConfigTimer(); + if (!WriteConfig()) { Broadcast("Writing the config file failed", true); } else if (eState == ECONFIG_NEED_VERBOSE_WRITE) { @@ -490,6 +521,7 @@ bool CZNC::WriteConfig() { CString(m_bProtectWebSessions)); config.AddKeyValuePair("HideVersion", CString(m_bHideVersion)); config.AddKeyValuePair("Version", CString(VERSION_STR)); + config.AddKeyValuePair("ConfigWriteDelay", CString(m_uiConfigWriteDelay)); unsigned int l = 0; for (CListener* pListener : m_vpListeners) { @@ -1224,6 +1256,8 @@ bool CZNC::LoadGlobal(CConfig& config, CString& sError) { return false; } } + if (config.FindStringEntry("configwritedelay", sVal)) + m_uiConfigWriteDelay = sVal.ToUInt(); UnloadRemovedModules(msModules); @@ -2121,3 +2155,10 @@ void CZNC::LeakConnectQueueTimer(CConnectQueueTimer* pTimer) { } bool CZNC::WaitForChildLock() { return m_pLockFile && m_pLockFile->ExLock(); } + +void CZNC::DisableConfigTimer() { + if (m_pConfigTimer) { + m_pConfigTimer->Stop(); + m_pConfigTimer = nullptr; + } +} From 2494bd722a58f34e98ce3ce7042e7b9cb6023566 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 8 Mar 2016 13:55:45 -0500 Subject: [PATCH 2/2] Change Channel SetInConfig/SetKey to use ECONFIG_DELAYED_WRITE --- src/Chan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Chan.cpp b/src/Chan.cpp index 54880783..9fb4ce72 100644 --- a/src/Chan.cpp +++ b/src/Chan.cpp @@ -700,7 +700,7 @@ void CChan::SetKey(const CString& s) { if (m_sKey != s) { m_sKey = s; if (m_bInConfig) { - CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_WRITE); + CZNC::Get().SetConfigState(CZNC::ECONFIG_DELAYED_WRITE); } } } @@ -708,7 +708,7 @@ void CChan::SetKey(const CString& s) { void CChan::SetInConfig(bool b) { if (m_bInConfig != b) { m_bInConfig = b; - CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_WRITE); + CZNC::Get().SetConfigState(CZNC::ECONFIG_DELAYED_WRITE); } }