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
|
Log.h
|
||||||
ProgressBar.cpp
|
ProgressBar.cpp
|
||||||
ProgressBar.h
|
ProgressBar.h
|
||||||
|
SignalHandler.h
|
||||||
Threading.cpp
|
Threading.cpp
|
||||||
Timer.h
|
Timer.h
|
||||||
Util.cpp
|
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
|
\ingroup Trinityd
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ace/OS_NS_signal.h>
|
#include <ace/Sig_Handler.h>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "SystemConfig.h"
|
#include "SystemConfig.h"
|
||||||
|
#include "SignalHandler.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "WorldRunnable.h"
|
#include "WorldRunnable.h"
|
||||||
#include "WorldSocket.h"
|
#include "WorldSocket.h"
|
||||||
@@ -60,6 +61,28 @@ INSTANTIATE_SINGLETON_1( Master );
|
|||||||
|
|
||||||
volatile uint32 Master::m_masterLoopCounter = 0;
|
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
|
class FreezeDetectorRunnable : public ACE_Based::Runnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -233,8 +256,21 @@ int Master::Run()
|
|||||||
///- Initialize the World
|
///- Initialize the World
|
||||||
sWorld.SetInitialWorldSettings();
|
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
|
///- Launch WorldRunnable thread
|
||||||
ACE_Based::Thread world_thread(new WorldRunnable);
|
ACE_Based::Thread world_thread(new WorldRunnable);
|
||||||
@@ -329,9 +365,6 @@ int Master::Run()
|
|||||||
// set server offline
|
// set server offline
|
||||||
LoginDatabase.PExecute("UPDATE realmlist SET color = 2 WHERE id = '%d'",realmID);
|
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
|
// when the main thread closes the singletons get unloaded
|
||||||
// since worldrunnable uses them, it will crash if unloaded after master
|
// since worldrunnable uses them, it will crash if unloaded after master
|
||||||
world_thread.wait();
|
world_thread.wait();
|
||||||
@@ -507,44 +540,3 @@ void Master::clearOnlineAccounts()
|
|||||||
// Battleground instance ids reset at server restart
|
// Battleground instance ids reset at server restart
|
||||||
CharacterDatabase.Execute("UPDATE character_battleground_data SET instance_id = 0");
|
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:
|
private:
|
||||||
bool _StartDB();
|
bool _StartDB();
|
||||||
|
|
||||||
void _HookSignals();
|
|
||||||
void _UnhookSignals();
|
|
||||||
static void _OnSignal(int s);
|
|
||||||
|
|
||||||
void clearOnlineAccounts();
|
void clearOnlineAccounts();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+37
-50
@@ -29,11 +29,13 @@
|
|||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "SystemConfig.h"
|
#include "SystemConfig.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
#include "SignalHandler.h"
|
||||||
#include "RealmList.h"
|
#include "RealmList.h"
|
||||||
#include "RealmAcceptor.h"
|
#include "RealmAcceptor.h"
|
||||||
|
|
||||||
#include <ace/Dev_Poll_Reactor.h>
|
#include <ace/Dev_Poll_Reactor.h>
|
||||||
#include <ace/ACE.h>
|
#include <ace/ACE.h>
|
||||||
|
#include <ace/Sig_Handler.h>
|
||||||
|
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
@@ -57,13 +59,33 @@ int m_ServiceStatus = -1;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool StartDB();
|
bool StartDB();
|
||||||
void UnhookSignals();
|
|
||||||
void HookSignals();
|
|
||||||
|
|
||||||
bool stopEvent = false; ///< Setting it to true stops the server
|
bool stopEvent = false; ///< Setting it to true stops the server
|
||||||
|
|
||||||
DatabaseType LoginDatabase; ///< Accessor to the realm server database
|
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.
|
/// Print out the usage string for this program on the console.
|
||||||
void usage(const char *prog)
|
void usage(const char *prog)
|
||||||
{
|
{
|
||||||
@@ -214,8 +236,19 @@ extern int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
///- Catch termination signals
|
// Initialise the signal handlers
|
||||||
HookSignals();
|
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
|
///- Handle affinity for multiple processors and process priority on Windows
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -303,34 +336,10 @@ extern int main(int argc, char **argv)
|
|||||||
LoginDatabase.ThreadEnd();
|
LoginDatabase.ThreadEnd();
|
||||||
LoginDatabase.HaltDelayThread();
|
LoginDatabase.HaltDelayThread();
|
||||||
|
|
||||||
///- Remove signal handling before leaving
|
|
||||||
UnhookSignals();
|
|
||||||
|
|
||||||
sLog.outString("Halting process...");
|
sLog.outString("Halting process...");
|
||||||
return 0;
|
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
|
/// Initialize connection to the database
|
||||||
bool StartDB()
|
bool StartDB()
|
||||||
{
|
{
|
||||||
@@ -351,26 +360,4 @@ bool StartDB()
|
|||||||
return true;
|
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"
|
RelativePath="..\..\src\shared\ServiceWin32.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\shared\SignalHandler.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\shared\SystemConfig.h"
|
RelativePath="..\..\src\shared\SystemConfig.h"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user