Change the freeze detector thread to be a periodic callback running on the thread pool

This commit is contained in:
leak
2014-07-06 23:04:38 +02:00
parent 32f5286d05
commit 59c8ffe4b3
2 changed files with 28 additions and 23 deletions

View File

@@ -23,6 +23,7 @@
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
#include <boost/asio/io_service.hpp>
#include <boost/asio/deadline_timer.hpp>
#include "Common.h"
#include "DatabaseEnv.h"
@@ -62,6 +63,11 @@ int m_ServiceStatus = -1;
#endif
boost::asio::io_service _ioService;
boost::asio::deadline_timer _freezeCheckTimer(_ioService);
uint32 _worldLoopCounter(0);
uint32 _lastChangeMsTime(0);
uint32 _maxCoreStuckTime(0);
WorldDatabaseWorkerPool WorldDatabase; ///< Accessor to the world database
CharacterDatabaseWorkerPool CharacterDatabase; ///< Accessor to the character database
LoginDatabaseWorkerPool LoginDatabase; ///< Accessor to the realm/login database
@@ -69,7 +75,7 @@ uint32 realmID; ///< Id of the realm
void usage(const char* prog);
void SignalHandler(const boost::system::error_code& error, int signalNumber);
void FreezeDetectorThread(uint32 delayTime);
void FreezeDetectorHandler(const boost::system::error_code& error);
AsyncAcceptor<RASession>* StartRaSocketAcceptor(boost::asio::io_service& ioService);
bool StartDB();
void StopDB();
@@ -219,11 +225,6 @@ extern int main(int argc, char** argv)
soapThread = new std::thread(TCSoapThread, sConfigMgr->GetStringDefault("SOAP.IP", "127.0.0.1"), uint16(sConfigMgr->GetIntDefault("SOAP.Port", 7878)));
}
// Start up freeze catcher thread
std::thread* freezeDetectorThread = nullptr;
if (uint32 freezeDelay = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0))
freezeDetectorThread = new std::thread(FreezeDetectorThread, freezeDelay);
// Launch the worldserver listener socket
uint16 worldPort = uint16(sWorld->getIntConfig(CONFIG_PORT_WORLD));
std::string worldListener = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
@@ -235,6 +236,15 @@ extern int main(int argc, char** argv)
// Set server online (allow connecting now)
LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID);
// Start the freeze check callback cycle in 5 seconds (cycle itself is 1 sec)
std::thread* freezeDetectorThread = nullptr;
if (_maxCoreStuckTime = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0))
{
_freezeCheckTimer.expires_from_now(boost::posix_time::seconds(5));
_freezeCheckTimer.async_wait(FreezeDetectorHandler);
TC_LOG_INFO("server.worldserver", "Starting up anti-freeze thread (%u seconds max stuck time)...", _maxCoreStuckTime);
}
TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon) ready...", _FULLVERSION);
WorldUpdateLoop();
@@ -408,34 +418,28 @@ void SignalHandler(const boost::system::error_code& error, int signalNumber)
}
}
void FreezeDetectorThread(uint32 delayTime)
void FreezeDetectorHandler(const boost::system::error_code& error)
{
if (!delayTime)
return;
TC_LOG_INFO("server.worldserver", "Starting up anti-freeze thread (%u seconds max stuck time)...", delayTime / 1000);
uint32 loops = 0;
uint32 lastChange = 0;
while (!World::IsStopped())
if (!error)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
uint32 curtime = getMSTime();
// normal work
uint32 worldLoopCounter = World::m_worldLoopCounter;
if (loops != worldLoopCounter)
if (_worldLoopCounter != worldLoopCounter)
{
lastChange = curtime;
loops = worldLoopCounter;
_lastChangeMsTime = curtime;
_worldLoopCounter = worldLoopCounter;
}
// possible freeze
else if (getMSTimeDiff(lastChange, curtime) > delayTime)
else if (getMSTimeDiff(_lastChangeMsTime, curtime) > _maxCoreStuckTime)
{
TC_LOG_ERROR("server.worldserver", "World Thread hangs, kicking out server!");
ASSERT(false);
}
_freezeCheckTimer.expires_from_now(boost::posix_time::seconds(1));
_freezeCheckTimer.async_wait(FreezeDetectorHandler);
}
TC_LOG_INFO("server.worldserver", "Anti-freeze thread exiting without problems.");
}
AsyncAcceptor<RASession>* StartRaSocketAcceptor(boost::asio::io_service& ioService)