Default initialize class thread variables

During testing in a sandbox environment, xlxd crashed in
CG3Protocol::Close(). The root cause was dereferencing
m_pPresenceThread when the object had never been initialized.
In this case an error occured during ::Init() which set ok=false,
so the initialization of the threads was skipped.

This commit does 3 things:

(1) Default initializes the thread pointers to avoid the crash.
(2) Wraps the thread allocation with try/catch since std::thread can
    throw.
(3) Does some light cleaning in ::Close, e.g., converting NULL to
    nullptr.
This commit is contained in:
Mark Landis (N6AZX) 2022-12-17 14:58:25 -08:00
parent 6752c7b254
commit d4c72fd623
2 changed files with 25 additions and 11 deletions

View file

@ -79,9 +79,17 @@ bool CG3Protocol::Init(void)
if (ok) if (ok)
{ {
// start helper threads // start helper threads
try
{
m_pPresenceThread = new std::thread(PresenceThread, this); m_pPresenceThread = new std::thread(PresenceThread, this);
m_pPresenceThread = new std::thread(ConfigThread, this); m_pConfigThread = new std::thread(ConfigThread, this);
m_pPresenceThread = new std::thread(IcmpThread, this); m_pIcmpThread = new std::thread(IcmpThread, this);
}
catch (const std::system_error& e)
{
ok = false;
// ... threads will be cleaned up on the call to ::Close()
}
} }
#endif #endif
@ -94,25 +102,25 @@ bool CG3Protocol::Init(void)
void CG3Protocol::Close(void) void CG3Protocol::Close(void)
{ {
if (m_pPresenceThread != NULL) if (m_pPresenceThread)
{ {
m_pPresenceThread->join(); m_pPresenceThread->join();
delete m_pPresenceThread; delete m_pPresenceThread;
m_pPresenceThread = NULL; m_pPresenceThread = nullptr;
} }
if (m_pConfigThread != NULL) if (m_pConfigThread)
{ {
m_pConfigThread->join(); m_pConfigThread->join();
delete m_pConfigThread; delete m_pConfigThread;
m_pConfigThread = NULL; m_pConfigThread = nullptr;
} }
if (m_pIcmpThread != NULL) if (m_pIcmpThread)
{ {
m_pIcmpThread->join(); m_pIcmpThread->join();
delete m_pIcmpThread; delete m_pIcmpThread;
m_pIcmpThread = NULL; m_pIcmpThread = nullptr;
} }
} }
@ -600,7 +608,7 @@ bool CG3Protocol::OnDvHeaderPacketIn(CDvHeaderPacket *Header, const CIp &Ip)
// drop if invalid module // drop if invalid module
delete Header; delete Header;
g_Reflector.ReleaseClients(); g_Reflector.ReleaseClients();
return NULL; return false;
} }
} }

View file

@ -64,7 +64,13 @@ class CG3Protocol : public CProtocol
{ {
public: public:
// constructor // constructor
CG3Protocol() : m_GwAddress(0u), m_Modules("*"), m_LastModTime(0) {}; CG3Protocol() :
m_GwAddress(0u),
m_Modules("*"),
m_LastModTime(0),
m_pPresenceThread(nullptr),
m_pConfigThread(nullptr),
m_pIcmpThread(nullptr) {}
// destructor // destructor
virtual ~CG3Protocol() {}; virtual ~CG3Protocol() {};