8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 02:43:04 +01:00

Improved reaction on Ctrl+C\Ctrl+Break\console close request in Trace Manager and Services Manager console utilities on Windows.

This commit is contained in:
hvlad 2015-11-03 11:01:57 +00:00
parent 23975e8614
commit a6c1a84ab3
5 changed files with 87 additions and 47 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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<const char*>(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;
}

View File

@ -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<UCHAR, 1024> 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<unsigned char>(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<UtilSvc> uSvc(UtilSvc::createStandalone(argc, argv));