break;
case SIGUSR1:
CUtils::PrintMessage("Caught SIGUSR1");
- CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_WRITE);
+ CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_VERBOSE_WRITE);
break;
default:
CUtils::PrintMessage("WTF? Signal handler called for a signal it doesn't know?");
vector<CChan*>::const_iterator it = vChans.begin();
vector<CChan*>::const_iterator end = vChans.end();
- m_bWriteConf = false;
-
for (; it != end; ++it) {
CChan *pChan = *it;
// we'll have to add it...
if (!pChan->InConfig()) {
pChan->SetInConfig(true);
- m_bWriteConf = true;
+ CZNC::Get().SetConfigState(CZNC::ECONFIG_WANT_WRITE);
}
}
}
virtual ~CChanSaverMod() {
}
- virtual EModRet OnRaw(CString& sLine) {
- if (m_bWriteConf) {
- CZNC::Get().WriteConfig();
- m_bWriteConf = false;
- }
-
- return CONTINUE;
- }
-
virtual void OnMode(const CNick& OpNick, CChan& Channel, char uMode, const CString& sArg, bool bAdded, bool bNoChange) {
// This is called when we join (ZNC requests the channel modes
// on join) *and* when someone changes the channel keys.
return;
Channel.SetKey(sArg);
- m_bWriteConf = true;
+ CZNC::Get().SetConfigState(CZNC::ECONFIG_WANT_WRITE);
}
virtual void OnJoin(const CNick& Nick, CChan& Channel) {
if (Nick.GetNick() == m_pUser->GetIRCNick().GetNick() && !Channel.InConfig()) {
Channel.SetInConfig(true);
- CZNC::Get().WriteConfig();
+ CZNC::Get().SetConfigState(CZNC::ECONFIG_WANT_WRITE);
}
}
virtual void OnPart(const CNick& Nick, CChan& Channel, const CString& sMessage) {
if (Nick.GetNick() == m_pUser->GetIRCNick().GetNick() && Channel.InConfig()) {
Channel.SetInConfig(false);
- CZNC::Get().WriteConfig();
+ CZNC::Get().SetConfigState(CZNC::ECONFIG_WANT_WRITE);
}
}
if (sKickedNick == m_pUser->GetIRCNick().GetNick() && Channel.InConfig())
{
Channel.SetInConfig(false);
- CZNC::Get().WriteConfig();
+ CZNC::Get().SetConfigState(CZNC::ECONFIG_WANT_WRITE);
}
}
-
-private:
- bool m_bWriteConf;
};
template<> void TModInfo<CChanSaverMod>(CModInfo& Info) {
#include "Config.h"
#include <list>
+#define CONFIG_WRITE_INTERVAL (60 * 5)
+
static inline CString FormatBindError() {
CString sError = (errno == 0 ? CString("unknown error, check the host name") : CString(strerror(errno)));
return "Unable to bind [" + sError + "]";
m_sConnectThrottle.SetTTL(30000);
m_pLockFile = NULL;
m_bProtectWebSessions = true;
+ m_pConfigTimer = NULL;
}
CZNC::~CZNC() {
return true;
}
+class CConfigWriteTimer : public CCron {
+ public:
+ CConfigWriteTimer(int iSecs) : CCron() {
+ SetName("Config write timer");
+ Start(iSecs);
+ }
+
+ protected:
+ void RunJob() {
+ CZNC::Get().SetConfigState(CZNC::ECONFIG_NEED_WRITE);
+
+ CZNC::Get().DisableConfigTimer();
+ }
+};
+
void CZNC::Loop() {
while (true) {
CString sError;
- switch (GetConfigState()) {
+ ConfigState eState = GetConfigState();
+ switch (eState) {
case ECONFIG_NEED_REHASH:
SetConfigState(ECONFIG_NOTHING);
Broadcast("ZNC is in some possibly inconsistent state!", true);
}
break;
+ case ECONFIG_WANT_WRITE:
+ SetConfigState(ECONFIG_NOTHING);
+
+ if (m_pConfigTimer == NULL) {
+ m_pConfigTimer = new CConfigWriteTimer(CONFIG_WRITE_INTERVAL);
+ GetManager().AddCron(m_pConfigTimer);
+ }
+ break;
case ECONFIG_NEED_WRITE:
+ case ECONFIG_NEED_VERBOSE_WRITE:
SetConfigState(ECONFIG_NOTHING);
- if (WriteConfig()) {
- Broadcast("Writing the config succeeded", true);
- } else {
+ if (!WriteConfig()) {
Broadcast("Writing the config file failed", true);
+ } else if (eState == ECONFIG_NEED_VERBOSE_WRITE) {
+ Broadcast("Writing the config succeeded", true);
}
break;
case ECONFIG_NOTHING:
bool CZNC::WaitForChildLock() {
return m_pLockFile && m_pLockFile->ExLock();
}
+
+void CZNC::DisableConfigTimer() {
+ if (m_pConfigTimer) {
+ m_pConfigTimer->Stop();
+ m_pConfigTimer = NULL;
+ }
+}
class CListener;
class CUser;
class CConnectUserTimer;
+class CConfigWriteTimer;
class CConfig;
class CFile;
enum ConfigState {
ECONFIG_NOTHING,
ECONFIG_NEED_REHASH,
- ECONFIG_NEED_WRITE
+ ECONFIG_NEED_WRITE,
+ ECONFIG_NEED_VERBOSE_WRITE,
+ ECONFIG_WANT_WRITE
};
void DeleteUsers();
// Never call this unless you are CConnectUserTimer::~CConnectUserTimer()
void LeakConnectUser(CConnectUserTimer *pTimer);
+ void DisableConfigTimer();
+
static void DumpConfig(const CConfig* Config);
private:
CConnectUserTimer *m_pConnectUserTimer;
TCacheMap<CString> m_sConnectThrottle;
bool m_bProtectWebSessions;
+ CConfigWriteTimer *m_pConfigTimer;
};
#endif // !_ZNC_H