I'm trying to make a graceful exit from a console app when the close button is hit.
bool done = false;
BOOL ctrl_handler(DWORD event)
{
if (event == CTRL_CLOSE_EVENT) {
done = true;
return TRUE;
}
return FALSE;
}
int main()
{
SetConsoleCtrlHandler((PHANDLER_ROUTINE)(ctrl_handler), TRUE);
while (!done)
do_stuff();
cleanup();
cout << "bye";
}
My handler gets called properly but the main thread does not resume afterwards so the "bye" never happens. If I trap CTRL_C_EVENT instead and hit ^C in the console then the main thread is allowed to continue and exits gracefully. Is there some way to allow the main thread to exit gracefully on console close?
I've also tried using std::signal but it's the same. Works for ^C but not for window close.
Thanks Jonathan for the tip.
I saw that the handler is called on it's own thread. If the handler returns then the whole process is forced to exit so we need to give the main thread time to exit on its own.
bool done = false;
BOOL ctrl_handler(DWORD event)
{
if (event == CTRL_CLOSE_EVENT) {
done = true;
Sleep(20000); // force exit after 20 seconds
return TRUE;
}
return FALSE;
}
int main()
{
SetConsoleCtrlHandler((PHANDLER_ROUTINE)(ctrl_handler), TRUE);
while (!done)
do_stuff();
cleanup();
cout << "bye";
}
I think the better way would be to use:
if (event == CTRL_CLOSE_EVENT)
{
ExitThread(0);
// return TRUE; // warning C4702: unreachable code
}
The ExitThread
will terminate the thread from which ctrl_handler
gets called. This way ExitProcess
will not be called, and your main thread will be able to perform all the needed cleanup.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With