diff --git a/src/common/Utilities/SignalHandler.h b/src/common/Utilities/SignalHandler.h index 5755d45a3..2ddfb810d 100644 --- a/src/common/Utilities/SignalHandler.h +++ b/src/common/Utilities/SignalHandler.h @@ -4,26 +4,41 @@ * Copyright (C) 2005-2009 MaNGOS */ -#ifndef __SIGNAL_HANDLER_H__ -#define __SIGNAL_HANDLER_H__ +#ifndef _SIGNAL_HANDLER_H_ +#define _SIGNAL_HANDLER_H_ -#include +#include +#include +#include namespace acore { - /// Handle termination signals - class SignalHandler : public ACE_Event_Handler + class SignalHandler { - public: - int handle_signal(int SigNum, siginfo_t* = nullptr, ucontext_t* = nullptr) override - { - HandleSignal(SigNum); - return 0; - } - virtual void HandleSignal(int /*SigNum*/) { }; - }; + private: + std::unordered_set _handled; + mutable std::mutex _mutex; + public: + bool handle_signal(int sig, void (*func)(int)) + { + std::lock_guard lock(_mutex); + + if (_handled.find(sig) != _handled.end()) + return false; + + _handled.insert(sig); + signal(sig, func); + return true; + } + + ~SignalHandler() + { + for (auto const& sig : _handled) + signal(sig, nullptr); + } + }; } -#endif /* __SIGNAL_HANDLER_H__ */ +#endif // _SIGNAL_HANDLER_H_ diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index 779e46dfb..c8961ce29 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -46,22 +45,6 @@ bool stopEvent = false; // Setting it to tru LoginDatabaseWorkerPool LoginDatabase; // Accessor to the authserver database -/// Handle authserver's termination signals -class AuthServerSignalHandler : public acore::SignalHandler -{ -public: - void HandleSignal(int sigNum) override - { - switch (sigNum) - { - case SIGINT: - case SIGTERM: - stopEvent = true; - break; - } - } -}; - /// Print out the usage string for this program on the console. void usage(const char* prog) { @@ -180,12 +163,15 @@ extern int main(int argc, char** argv) sLog->outString("Authserver listening to %s:%d", bind_ip.c_str(), rmport); // Initialize the signal handlers - AuthServerSignalHandler SignalINT, SignalTERM; + acore::SignalHandler signalHandler; + auto const _handler = [](int) { stopEvent = true; }; // Register authservers's signal handlers - ACE_Sig_Handler Handler; - Handler.register_handler(SIGINT, &SignalINT); - Handler.register_handler(SIGTERM, &SignalTERM); + signalHandler.handle_signal(SIGINT, _handler); + signalHandler.handle_signal(SIGTERM, _handler); +#if AC_PLATFORM == AC_PLATFORM_WINDOWS + signalHandler.handle_signal(SIGBREAK, _handler); +#endif #if defined(_WIN32) || defined(__linux__) diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index 051cab75f..588e26009 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -43,30 +43,28 @@ extern int m_ServiceStatus; #endif /// Handle worldservers's termination signals -class WorldServerSignalHandler : public acore::SignalHandler +void HandleSignal(int sigNum) { -public: - void HandleSignal(int sigNum) override + switch (sigNum) { - switch (sigNum) - { - case SIGINT: - World::StopNow(RESTART_EXIT_CODE); - break; - case SIGTERM: -#ifdef _WIN32 - case SIGBREAK: - if (m_ServiceStatus != 1) + case SIGINT: + World::StopNow(RESTART_EXIT_CODE); + break; + case SIGTERM: +#if AC_PLATFORM == AC_PLATFORM_WINDOWS + case SIGBREAK: + if (m_ServiceStatus != 1) #endif - World::StopNow(SHUTDOWN_EXIT_CODE); - break; - /*case SIGSEGV: - sLog->outString("ZOMG! SIGSEGV handled!"); - World::StopNow(SHUTDOWN_EXIT_CODE); - break;*/ - } + World::StopNow(SHUTDOWN_EXIT_CODE); + break; + /*case SIGSEGV: + sLog->outString("ZOMG! SIGSEGV handled!"); + World::StopNow(SHUTDOWN_EXIT_CODE); + break;*/ + default: + break; } -}; +} class FreezeDetectorRunnable : public acore::Runnable { @@ -164,19 +162,14 @@ int Master::Run() sScriptMgr->OnStartup(); ///- Initialize the signal handlers - WorldServerSignalHandler signalINT, signalTERM; //, signalSEGV -#ifdef _WIN32 - WorldServerSignalHandler signalBREAK; -#endif /* _WIN32 */ + acore::SignalHandler signalHandler; - ///- Register worldserver's signal handlers - ACE_Sig_Handler handle; - handle.register_handler(SIGINT, &signalINT); - handle.register_handler(SIGTERM, &signalTERM); -#ifdef _WIN32 - handle.register_handler(SIGBREAK, &signalBREAK); + signalHandler.handle_signal(SIGINT, &HandleSignal); + signalHandler.handle_signal(SIGTERM, &HandleSignal); + +#if AC_PLATFORM == AC_PLATFORM_WINDOWS + signalHandler.handle_signal(SIGBREAK, &HandleSignal); #endif - //handle.register_handler(SIGSEGV, &signalSEGV); ///- Launch WorldRunnable thread acore::Thread worldThread(new WorldRunnable);