From a6c1a84ab351662c3e08c84f7a7d5f46b3be06ff Mon Sep 17 00:00:00 2001 From: hvlad Date: Tue, 3 Nov 2015 11:01:57 +0000 Subject: [PATCH] Improved reaction on Ctrl+C\Ctrl+Break\console close request in Trace Manager and Services Manager console utilities on Windows. --- src/common/os/os_utils.h | 25 +++++++++++++++++ src/common/os/posix/os_utils.cpp | 24 +++++++++++++++++ src/common/os/win32/os_utils.cpp | 29 ++++++++++++++++++++ src/utilities/fbsvcmgr/fbsvcmgr.cpp | 23 ++++------------ src/utilities/fbtracemgr/traceMgrMain.cpp | 33 +++-------------------- 5 files changed, 87 insertions(+), 47 deletions(-) diff --git a/src/common/os/os_utils.h b/src/common/os/os_utils.h index 56c4db8e32..f9f1442544 100644 --- a/src/common/os/os_utils.h +++ b/src/common/os/os_utils.h @@ -69,6 +69,31 @@ namespace os_utils #define HAVE_ID_BY_NAME void getUniqueFileId(const char* name, Firebird::UCharBuffer& id); #endif + + + class CtrlCHandler + { + public: + CtrlCHandler(); + ~CtrlCHandler(); + + bool getTerminated() const + { + return terminated; + } + + private: + static bool terminated; + +#ifdef WIN_NT + static BOOL WINAPI handler(DWORD dwCtrlType); +#else + static void handler(void*); + + bool procInt; + bool procTerm; +#endif + }; } // namespace os_utils #endif // INCLUDE_OS_FILE_UTILS_H diff --git a/src/common/os/posix/os_utils.cpp b/src/common/os/posix/os_utils.cpp index 5000ac7239..9cadf6df97 100644 --- a/src/common/os/posix/os_utils.cpp +++ b/src/common/os/posix/os_utils.cpp @@ -31,6 +31,7 @@ #include "../common/classes/init.h" #include "../common/gdsassert.h" #include "../common/os/os_utils.h" +#include "../common/os/isc_i_proto.h" #include "../jrd/constants.h" #ifdef HAVE_UNISTD_H @@ -323,4 +324,27 @@ void getUniqueFileId(const char* name, UCharBuffer& id) makeUniqueFileId(statistics, id); } +/// class CtrlCHandler + +bool CtrlCHandler::terminated = false; + +CtrlCHandler::CtrlCHandler() +{ + procInt = ISC_signal(SIGINT, handler, 0); + procTerm = ISC_signal(SIGTERM, handler, 0); +} + +CtrlCHandler::~CtrlCHandler() +{ + if (procInt) + ISC_signal_cancel(SIGINT, handler, 0); + if (procTerm) + ISC_signal_cancel(SIGTERM, handler, 0); +} + +void CtrlCHandler::handler(void*) +{ + terminated = true; +} + } // namespace os_utils diff --git a/src/common/os/win32/os_utils.cpp b/src/common/os/win32/os_utils.cpp index 207eb647d5..15faee1e4d 100644 --- a/src/common/os/win32/os_utils.cpp +++ b/src/common/os/win32/os_utils.cpp @@ -336,4 +336,33 @@ void getUniqueFileId(HANDLE fd, Firebird::UCharBuffer& id) } +/// class CtrlCHandler + +bool CtrlCHandler::terminated = false; + +CtrlCHandler::CtrlCHandler() +{ + SetConsoleCtrlHandler(handler, TRUE); +} + +CtrlCHandler::~CtrlCHandler() +{ + SetConsoleCtrlHandler(handler, FALSE); +} + +BOOL WINAPI CtrlCHandler::handler(DWORD dwCtrlType) +{ + switch (dwCtrlType) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + case CTRL_CLOSE_EVENT: + terminated = true; + return TRUE; + + default: + return FALSE; + } +} + } // namespace os_utils diff --git a/src/utilities/fbsvcmgr/fbsvcmgr.cpp b/src/utilities/fbsvcmgr/fbsvcmgr.cpp index f70d1832f3..6b979681ba 100644 --- a/src/utilities/fbsvcmgr/fbsvcmgr.cpp +++ b/src/utilities/fbsvcmgr/fbsvcmgr.cpp @@ -42,6 +42,7 @@ #include "../common/utils_proto.h" #include "../common/classes/MsgPrint.h" #include "../common/StatusArg.h" +#include "../common/os/os_utils.h" #include "../jrd/license.h" #ifdef HAVE_LOCALE_H @@ -998,20 +999,6 @@ void usage(bool listSwitches) } -typedef void (*SignalHandlerPointer)(int); - -static SignalHandlerPointer prevCtrlCHandler = NULL; -static bool terminated = false; - -static void ctrl_c_handler(int signal) -{ - terminated = true; - printf("\n"); - - if (prevCtrlCHandler) - prevCtrlCHandler(signal); -} - static void atexit_fb_shutdown() { fb_shutdown(0, fb_shutrsn_app_stopped); @@ -1039,7 +1026,7 @@ int main(int ac, char** av) return 0; } - prevCtrlCHandler = signal(SIGINT, ctrl_c_handler); + os_utils::CtrlCHandler ctrlCHandler; atexit(&atexit_fb_shutdown); ISC_STATUS_ARRAY status; @@ -1175,17 +1162,17 @@ int main(int ac, char** av) reinterpret_cast(spbItems.getBuffer()), sizeof(results), results)) { - if (!terminated) + if (!ctrlCHandler.getTerminated()) isc_print_status(status); isc_service_detach(status, &svc_handle); return 1; } - } while (printInfo(results, sizeof(results), uPrint, stdinRequest) && !terminated); + } while (printInfo(results, sizeof(results), uPrint, stdinRequest) && !ctrlCHandler.getTerminated()); } if (isc_service_detach(status, &svc_handle)) { - if (!terminated) + if (!ctrlCHandler.getTerminated()) isc_print_status(status); return 1; } diff --git a/src/utilities/fbtracemgr/traceMgrMain.cpp b/src/utilities/fbtracemgr/traceMgrMain.cpp index 960a56b427..aab66df97c 100644 --- a/src/utilities/fbtracemgr/traceMgrMain.cpp +++ b/src/utilities/fbtracemgr/traceMgrMain.cpp @@ -32,6 +32,7 @@ #include "../../common/classes/auto.h" #include "../../common/classes/ClumpletWriter.h" #include "../../common/utils_proto.h" +#include "../../common/os/os_utils.h" #include "../../jrd/trace/TraceService.h" #include "../../jrd/ibase.h" @@ -55,20 +56,15 @@ public: virtual void setActive(ULONG id, bool active); virtual void listSessions(); - static void stopRead(); - private: void runService(size_t spbSize, const UCHAR* spb); isc_svc_handle m_svcHandle; - static bool m_stop; }; const int MAXBUF = 16384; -bool TraceSvcUtil::m_stop = true; - TraceSvcUtil::TraceSvcUtil() { m_svcHandle = 0; @@ -110,8 +106,6 @@ void TraceSvcUtil::setAttachInfo(const string& service_name, const string& user, void TraceSvcUtil::startSession(TraceSession& session, bool /*interactive*/) { - m_stop = false; - HalfStaticArray buff(*getDefaultMemoryPool()); UCHAR* p = NULL; long len = 0; @@ -198,13 +192,10 @@ void TraceSvcUtil::listSessions() runService(spb.getBufferLength(), spb.getBuffer()); } -void TraceSvcUtil::stopRead() -{ - m_stop = true; -} - void TraceSvcUtil::runService(size_t spbSize, const UCHAR* spb) { + os_utils::CtrlCHandler ctrlCHandler; + ISC_STATUS_ARRAY status; if (isc_service_start(status, &m_svcHandle, 0, @@ -288,7 +279,7 @@ void TraceSvcUtil::runService(size_t spbSize, const UCHAR* spb) Arg::Num(static_cast(p[-1]))); } } - } while (!(m_stop || noData)); + } while (!(ctrlCHandler.getTerminated() || noData)); } } // namespace Firebird @@ -296,21 +287,6 @@ void TraceSvcUtil::runService(size_t spbSize, const UCHAR* spb) using namespace Firebird; - -typedef void (*SignalHandlerPointer)(int); - -static SignalHandlerPointer prevCtrlCHandler = NULL; -static bool terminated = false; - -static void ctrl_c_handler(int signal) -{ - if (signal == SIGINT) - TraceSvcUtil::stopRead(); - - if (prevCtrlCHandler) - prevCtrlCHandler(signal); -} - static void atexit_fb_shutdown() { fb_shutdown(0, fb_shutrsn_app_stopped); @@ -334,7 +310,6 @@ int CLIB_ROUTINE main(int argc, char* argv[]) setlocale(LC_CTYPE, ""); #endif - prevCtrlCHandler = signal(SIGINT, ctrl_c_handler); atexit(&atexit_fb_shutdown); AutoPtr uSvc(UtilSvc::createStandalone(argc, argv));