

"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;
};

