[project @ 2004-11-17 19:07:38 by sof]
[ghc-hetmet.git] / ghc / rts / win32 / ConsoleHandler.c
index c8ef67d..a1d3bd9 100644 (file)
@@ -9,7 +9,6 @@
 #include "Schedule.h"
 #include "RtsUtils.h"
 #include "RtsFlags.h"
-#include "StablePriv.h"
 
 extern int stg_InstallConsoleEvent(int action, StgStablePtr *handler);
 
@@ -51,9 +50,11 @@ static BOOL WINAPI shutdown_handler(DWORD dwCtrlType)
 {
     switch (dwCtrlType) {
     
+    case CTRL_CLOSE_EVENT:
+       /* see generic_handler() comment re: this event */
+       return FALSE;
     case CTRL_C_EVENT:
     case CTRL_BREAK_EVENT:
-    case CTRL_CLOSE_EVENT:
 
        // If we're already trying to interrupt the RTS, terminate with
        // extreme prejudice.  So the first ^C tries to exit the program
@@ -81,9 +82,8 @@ static BOOL WINAPI shutdown_handler(DWORD dwCtrlType)
 void initDefaultHandlers(void)
 {
     if ( !SetConsoleCtrlHandler(shutdown_handler, TRUE) ) {
-       prog_belch("warning: failed to install default console handler");
+       errorBelch("warning: failed to install default console handler");
     }
-
 }
 
 
@@ -187,12 +187,23 @@ void handleSignalsInThisThread(void)
 static BOOL WINAPI generic_handler(DWORD dwCtrlType)
 {
     /* Ultra-simple -- up the counter + signal a switch. */
-    if ( stg_pending_events < N_PENDING_EVENTS ) {
-       stg_pending_buf[stg_pending_events] = dwCtrlType;
-       stg_pending_events++;
+    switch(dwCtrlType) {
+    case CTRL_CLOSE_EVENT:
+       /* Don't support the delivery of this event; if we
+        * indicate that we've handled it here and the Haskell handler
+        * doesn't take proper action (e.g., terminate the OS process),
+        * the user of the app will be unable to kill/close it. Not
+        * good, so disable the delivery for now.
+        */
+       return FALSE;
+    default:
+       if ( stg_pending_events < N_PENDING_EVENTS ) {
+           stg_pending_buf[stg_pending_events] = dwCtrlType;
+           stg_pending_events++;
+       }
+       context_switch = 1;
+       return TRUE;
     }
-    context_switch = 1;
-    return TRUE;
 }
 
 
@@ -210,19 +221,22 @@ stg_InstallConsoleEvent(int action, StgStablePtr *handler)
     case STG_SIG_IGN:
        console_handler = STG_SIG_IGN;
        if ( !SetConsoleCtrlHandler(NULL, TRUE) ) {
-           prog_belch("warning: unable to ignore console events");
+           errorBelch("warning: unable to ignore console events");
        }
        break;
     case STG_SIG_DFL:
        console_handler = STG_SIG_IGN;
        if ( !SetConsoleCtrlHandler(NULL, FALSE) ) {
-           prog_belch("warning: unable to restore default console event handling");
+           errorBelch("warning: unable to restore default console event handling");
        }
        break;
     case STG_SIG_HAN:
        console_handler = (StgInt)*handler;
-       if ( !SetConsoleCtrlHandler(generic_handler, TRUE) ) {
-           prog_belch("warning: unable to install console event handler");
+       if ( previous_hdlr < 0 ) {
+         /* Only install generic_handler() once */
+         if ( !SetConsoleCtrlHandler(generic_handler, TRUE) ) {
+           errorBelch("warning: unable to install console event handler");
+         }
        }
        break;
     }