1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
"John Buckman" <john@lyris.com>
I have not looked to see what you're using the signal handler for, but
just FYI, in our own Unix/Windows command line applications, we have a
Windows handler for ctrl-c and ctrl-break, which we use as substitutes
for signal handling on Windows. I can give you source code for doing
this if you like, if you think it is a useful substitute.
There are two functions you need. A handler routine and a routine
which registers that handler. The SetConsoleCtrlHandler() Windows
function set the handler, and then they handler just receives a signal
and returns either a true or false to ban on whether it was handled or
not.
Note that is only works in a console mode application and not in a
graphical application. The code below is copied directly out of
production source code working for several years, so there should not
be any bugs in it.
bool PlatformSpecificInitialize() {
LYRIS_PROFILE("PlatformSpecificInitialize");
bool retval;
retval = SetConsoleCtrlHandler(handler_routine, TRUE);
if (retval != TRUE) {
trace("Note: SetConsoleCtrlHandler() did not succeed.");
}
retval = SetConsoleTitle(APPLICATION_NAME.c_str());
if (retval != TRUE) {
trace("Note: setConsoleTitle() did not succeed.");
}
return lyris_success;
};
BOOL WINAPI handler_routine(DWORD signal) {
LYRIS_PROFILE("handler_routine");
static unsigned char handles_to_use = 3;
static bool handled_already = false;
if ((signal == CTRL_CLOSE_EVENT) || (signal == CTRL_SHUTDOWN_EVENT)) {
// if we receive a Windows signal to shutdown, we should exit
immediately, and cleanly
if (handled_already == false) {
handled_already = true;
//lyris_Thread::ExitApplicationNow();
DisplayMessage("Shutting down as requested");
// create shutdown thread so that signal handler can return
immediately
lyris_Thread aShutDown(ShutDownNow, NULL, "Shut Down
Thread");
return TRUE;
}
else {
return FALSE;
}
}
else if (signal == CTRL_C_EVENT) {
// if we receive a Windows signal to shutdown, we should exit
immediately, and cleanly
if (handles_to_use == 3) {
handles_to_use--;
//lyris_Thread::ExitApplicationNow();
DisplayMessage("Shutting down as requested");
// create shutdown thread so that signal handler can return
immediately
lyris_Thread aShutDown(ShutDownNow, NULL, "Shut Down
Thread");
return TRUE;
}
else if (handles_to_use > 0) {
DisplayMessage("Currently shutting down: press Ctrl-C " +
ULong2String(handles_to_use) + " more times to shut down immediately.");
handles_to_use--;
return TRUE;
}
else {
return FALSE;
}
}
else if (signal == CTRL_BREAK_EVENT) {
if (APPLICATION_NAME == "Lyris") {
if (ShouldDisplayDebugMessages() == 0) {
SetShouldDisplayDebugMessages(1);
}
else {
SetShouldDisplayDebugMessages(0);
}
DisplayMessage("Debug mode is now: " +
Bool2String(ShouldDisplayDebugMessages()));
}
else if (APPLICATION_NAME == "MailShield") {
specific::setReloadConfig(lyris_yes);
}
else {
lyr_fatal;
}
return TRUE;
}
else {
lyr_notify("Unknown Windows signal passed to handler: " +
ULong2String(signal));
};
return FALSE;
};
|