Fix a theoretical crash on shutdown

CZNC::~CZNC() set its pointer to the CConnectUserTimer to NULL and then called
the manager's Cleanup(). If some destructor that is called from here then calls
EnableConnectUser(), a new CConnectUserTimer is created and its address is
saved. But since the manager is destroying all timers, this pointer will soon
become dangling and might crash us later on.

This is solved by clearing CZNC's pointer in CConnectUserTimer's destructor.


git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1624 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
psychon
2009-09-10 18:27:56 +00:00
parent c3e87feb27
commit f1338fde5c
2 changed files with 20 additions and 1 deletions
+17 -1
View File
@@ -1794,7 +1794,18 @@ public:
// Don't wait iSecs seconds for first timer run
m_bRunOnNextCall = true;
}
virtual ~CConnectUserTimer() {}
virtual ~CConnectUserTimer() {
// This is only needed when ZNC shuts down:
// CZNC::~CZNC() sets its CConnectUserTimer pointer to NULL and
// calls the manager's Cleanup() which destroys all sockets and
// timers. If something calls CZNC::EnableConnectUser() here
// (e.g. because a CIRCSock is destroyed), the socket manager
// deletes that timer almost immediately, but CZNC now got a
// dangling pointer to this timer which can crash later on.
//
// Unlikely but possible ;)
CZNC::Get().LeakConnectUser(this);
}
protected:
virtual void RunJob() {
@@ -1870,3 +1881,8 @@ void CZNC::DisableConnectUser() {
m_pConnectUserTimer->Stop();
m_pConnectUserTimer = NULL;
}
void CZNC::LeakConnectUser(CConnectUserTimer *pTimer) {
if (m_pConnectUserTimer == pTimer)
m_pConnectUserTimer = NULL;
}
+3
View File
@@ -125,6 +125,9 @@ public:
void EnableConnectUser();
void DisableConnectUser();
// Never call this unless you are CConnectUserTimer::~CConnectUserTimer()
void LeakConnectUser(CConnectUserTimer *pTimer);
private:
bool DoRehash(CString& sError);
// Returns true if something was done