Implement a signalhandler via ACE.
Thanks to Diver for test compiling under WIN. --HG-- branch : trunk
This commit is contained in:
@@ -16,6 +16,7 @@ SET(shared_STAT_SRCS
|
||||
Log.h
|
||||
ProgressBar.cpp
|
||||
ProgressBar.h
|
||||
SignalHandler.h
|
||||
Threading.cpp
|
||||
Timer.h
|
||||
Util.cpp
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SIGNAL_HANDLER_H__
|
||||
#define __SIGNAL_HANDLER_H__
|
||||
|
||||
#include <ace/Event_Handler.h>
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
|
||||
/// Handle termination signals
|
||||
class SignalHandler : public ACE_Event_Handler
|
||||
{
|
||||
public:
|
||||
int handle_signal(int SigNum, siginfo_t* = NULL, ucontext_t* = NULL)
|
||||
{
|
||||
HandleSignal(SigNum);
|
||||
return 0;
|
||||
}
|
||||
virtual void HandleSignal(int SigNum) {};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* __SIGNAL_HANDLER_H__ */
|
||||
+39
-47
@@ -22,10 +22,11 @@
|
||||
\ingroup Trinityd
|
||||
*/
|
||||
|
||||
#include <ace/OS_NS_signal.h>
|
||||
#include <ace/Sig_Handler.h>
|
||||
|
||||
#include "Common.h"
|
||||
#include "SystemConfig.h"
|
||||
#include "SignalHandler.h"
|
||||
#include "World.h"
|
||||
#include "WorldRunnable.h"
|
||||
#include "WorldSocket.h"
|
||||
@@ -60,6 +61,28 @@ INSTANTIATE_SINGLETON_1( Master );
|
||||
|
||||
volatile uint32 Master::m_masterLoopCounter = 0;
|
||||
|
||||
/// Handle cored's termination signals
|
||||
class CoredSignalHandler : public Trinity::SignalHandler
|
||||
{
|
||||
public:
|
||||
virtual void HandleSignal(int SigNum)
|
||||
{
|
||||
switch (SigNum)
|
||||
{
|
||||
case SIGINT:
|
||||
World::StopNow(RESTART_EXIT_CODE);
|
||||
break;
|
||||
case SIGTERM:
|
||||
#ifdef _WIN32
|
||||
case SIGBREAK:
|
||||
if (m_ServiceStatus != 1)
|
||||
#endif /* _WIN32 */
|
||||
World::StopNow(SHUTDOWN_EXIT_CODE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FreezeDetectorRunnable : public ACE_Based::Runnable
|
||||
{
|
||||
public:
|
||||
@@ -233,8 +256,21 @@ int Master::Run()
|
||||
///- Initialize the World
|
||||
sWorld.SetInitialWorldSettings();
|
||||
|
||||
///- Catch termination signals
|
||||
_HookSignals();
|
||||
|
||||
// Initialise the signal handlers
|
||||
CoredSignalHandler SignalINT, SignalTERM;
|
||||
#ifdef _WIN32
|
||||
CoredSignalHandler SignalBREAK;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
// Register realmd's signal handlers
|
||||
ACE_Sig_Handler Handler;
|
||||
Handler.register_handler(SIGINT, &SignalINT);
|
||||
Handler.register_handler(SIGTERM, &SignalTERM);
|
||||
#ifdef _WIN32
|
||||
Handler.register_handler(SIGBREAK, &SignalBREAK);
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
||||
///- Launch WorldRunnable thread
|
||||
ACE_Based::Thread world_thread(new WorldRunnable);
|
||||
@@ -329,9 +365,6 @@ int Master::Run()
|
||||
// set server offline
|
||||
LoginDatabase.PExecute("UPDATE realmlist SET color = 2 WHERE id = '%d'",realmID);
|
||||
|
||||
///- Remove signal handling before leaving
|
||||
_UnhookSignals();
|
||||
|
||||
// when the main thread closes the singletons get unloaded
|
||||
// since worldrunnable uses them, it will crash if unloaded after master
|
||||
world_thread.wait();
|
||||
@@ -507,44 +540,3 @@ void Master::clearOnlineAccounts()
|
||||
// Battleground instance ids reset at server restart
|
||||
CharacterDatabase.Execute("UPDATE character_battleground_data SET instance_id = 0");
|
||||
}
|
||||
|
||||
/// Handle termination signals
|
||||
void Master::_OnSignal(int s)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case SIGINT:
|
||||
World::StopNow(RESTART_EXIT_CODE);
|
||||
break;
|
||||
case SIGTERM:
|
||||
#ifdef _WIN32
|
||||
case SIGBREAK:
|
||||
if (m_ServiceStatus != 1)
|
||||
#endif
|
||||
World::StopNow(SHUTDOWN_EXIT_CODE);
|
||||
break;
|
||||
}
|
||||
|
||||
signal(s, _OnSignal);
|
||||
}
|
||||
|
||||
/// Define hook '_OnSignal' for all termination signals
|
||||
void Master::_HookSignals()
|
||||
{
|
||||
signal(SIGINT, _OnSignal);
|
||||
signal(SIGTERM, _OnSignal);
|
||||
#ifdef _WIN32
|
||||
if (m_ServiceStatus != 1)
|
||||
signal(SIGBREAK, _OnSignal);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Unhook the signals before leaving
|
||||
void Master::_UnhookSignals()
|
||||
{
|
||||
signal(SIGINT, 0);
|
||||
signal(SIGTERM, 0);
|
||||
#ifdef _WIN32
|
||||
signal(SIGBREAK, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -40,10 +40,6 @@ class Master
|
||||
private:
|
||||
bool _StartDB();
|
||||
|
||||
void _HookSignals();
|
||||
void _UnhookSignals();
|
||||
static void _OnSignal(int s);
|
||||
|
||||
void clearOnlineAccounts();
|
||||
};
|
||||
|
||||
|
||||
+37
-50
@@ -29,11 +29,13 @@
|
||||
#include "Log.h"
|
||||
#include "SystemConfig.h"
|
||||
#include "Util.h"
|
||||
#include "SignalHandler.h"
|
||||
#include "RealmList.h"
|
||||
#include "RealmAcceptor.h"
|
||||
|
||||
#include <ace/Dev_Poll_Reactor.h>
|
||||
#include <ace/ACE.h>
|
||||
#include <ace/Sig_Handler.h>
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/crypto.h>
|
||||
@@ -57,13 +59,33 @@ int m_ServiceStatus = -1;
|
||||
#endif
|
||||
|
||||
bool StartDB();
|
||||
void UnhookSignals();
|
||||
void HookSignals();
|
||||
|
||||
bool stopEvent = false; ///< Setting it to true stops the server
|
||||
|
||||
DatabaseType LoginDatabase; ///< Accessor to the realm server database
|
||||
|
||||
/// Handle realmd's termination signals
|
||||
class RealmdSignalHandler : public Trinity::SignalHandler
|
||||
{
|
||||
public:
|
||||
virtual void HandleSignal(int SigNum)
|
||||
{
|
||||
switch (SigNum)
|
||||
{
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
stopEvent = true;
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
case SIGBREAK:
|
||||
if (m_ServiceStatus != 1)
|
||||
stopEvent = true;
|
||||
break;
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// Print out the usage string for this program on the console.
|
||||
void usage(const char *prog)
|
||||
{
|
||||
@@ -214,8 +236,19 @@ extern int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
///- Catch termination signals
|
||||
HookSignals();
|
||||
// Initialise the signal handlers
|
||||
RealmdSignalHandler SignalINT, SignalTERM;
|
||||
#ifdef _WIN32
|
||||
RealmdSignalHandler SignalBREAK;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
// Register realmd's signal handlers
|
||||
ACE_Sig_Handler Handler;
|
||||
Handler.register_handler(SIGINT, &SignalINT);
|
||||
Handler.register_handler(SIGTERM, &SignalTERM);
|
||||
#ifdef _WIN32
|
||||
Handler.register_handler(SIGBREAK, &SignalBREAK);
|
||||
#endif /* _WIN32 */();
|
||||
|
||||
///- Handle affinity for multiple processors and process priority on Windows
|
||||
#ifdef WIN32
|
||||
@@ -303,34 +336,10 @@ extern int main(int argc, char **argv)
|
||||
LoginDatabase.ThreadEnd();
|
||||
LoginDatabase.HaltDelayThread();
|
||||
|
||||
///- Remove signal handling before leaving
|
||||
UnhookSignals();
|
||||
|
||||
sLog.outString("Halting process...");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Handle termination signals
|
||||
/** Put the global variable stopEvent to 'true' if a termination signal is caught **/
|
||||
void OnSignal(int s)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
stopEvent = true;
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
case SIGBREAK:
|
||||
if (m_ServiceStatus != 1)
|
||||
stopEvent = true;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
signal(s, OnSignal);
|
||||
}
|
||||
|
||||
/// Initialize connection to the database
|
||||
bool StartDB()
|
||||
{
|
||||
@@ -351,26 +360,4 @@ bool StartDB()
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Define hook 'OnSignal' for all termination signals
|
||||
void HookSignals()
|
||||
{
|
||||
signal(SIGINT, OnSignal);
|
||||
signal(SIGTERM, OnSignal);
|
||||
#ifdef _WIN32
|
||||
if (m_ServiceStatus != 1)
|
||||
signal(SIGBREAK, OnSignal);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Unhook the signals before leaving
|
||||
void UnhookSignals()
|
||||
{
|
||||
signal(SIGINT, 0);
|
||||
signal(SIGTERM, 0);
|
||||
#ifdef _WIN32
|
||||
if (m_ServiceStatus != 1)
|
||||
signal(SIGBREAK, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -749,6 +749,10 @@
|
||||
RelativePath="..\..\src\shared\ServiceWin32.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\shared\SignalHandler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\shared\SystemConfig.h"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user