remove unnecessary/broken definition of mask_
[ghc-hetmet.git] / compiler / utils / Panic.lhs
index e6c385c..e11b28f 100644 (file)
@@ -17,7 +17,7 @@ module Panic
 
      panic, panicFastInt, assertPanic, trace,
      
-     Exception.Exception(..), showException, try, tryMost, tryUser, throwTo,
+     Exception.Exception(..), showException, try, tryMost, throwTo,
 
      installSignalHandlers, interruptTargetThread
    ) where
@@ -36,11 +36,11 @@ import GHC.ConsoleHandler
 #endif
 
 import Exception
-import Control.Concurrent ( MVar, ThreadId, withMVar, newMVar )
+import Control.Concurrent ( MVar, ThreadId, withMVar, newMVar, modifyMVar_,
+                            myThreadId )
 import Data.Dynamic
 import Debug.Trace     ( trace )
 import System.IO.Unsafe        ( unsafePerformIO )
-import System.IO.Error hiding ( try )
 import System.Exit
 import System.Environment
 \end{code}
@@ -63,7 +63,7 @@ ghcError e = Exception.throw e
 data GhcException
   = PhaseFailed String         -- name of phase 
                ExitCode        -- an external phase (eg. cpp) failed
-  | Interrupted                        -- someone pressed ^C
+  | Signal Int                  -- some other fatal signal (SIGHUP,SIGTERM)
   | UsageError String          -- prints the short usage msg after the error
   | CmdLineError String                -- cmdline prob, but doesn't print usage
   | Panic String               -- the `impossible' happened
@@ -106,8 +106,8 @@ showGhcException (ProgramError str)
    = showString str
 showGhcException (InstallationError str)
    = showString str
-showGhcException (Interrupted)
-   = showString "interrupted"
+showGhcException (Signal n)
+   = showString "signal: " . shows n
 showGhcException (Panic s)
    = showString ("panic! (the 'impossible' happened)\n"
                 ++ "  (GHC version " ++ cProjectVersion ++ " for " ++ TargetPlatform_NAME ++ "):\n\t"
@@ -148,7 +148,7 @@ assertPanic file line =
 \end{code}
 
 \begin{code}
--- | tryMost is like try, but passes through Interrupted and Panic
+-- | tryMost is like try, but passes through UserInterrupt and Panic
 -- exceptions.  Used when we want soft failures when reading interface
 -- files, for example.
 
@@ -159,7 +159,7 @@ tryMost action = do r <- try action
                         Left se ->
                             case fromException se of
                                 -- Some GhcException's we rethrow,
-                                Just Interrupted -> throwIO se
+                                Just (Signal _)  -> throwIO se
                                 Just (Panic _)   -> throwIO se
                                 -- others we return
                                 Just _           -> return (Left se)
@@ -171,21 +171,6 @@ tryMost action = do r <- try action
                                         -- Anything else is rethrown
                                         Nothing -> throwIO se
                         Right v -> return (Right v)
-
--- | tryUser is like try, but catches only UserErrors.
--- These are the ones that are thrown by the TcRn monad 
--- to signal an error in the program being compiled
-tryUser :: IO a -> IO (Either IOException a)
-tryUser io =
-    do ei <- try io
-       case ei of
-           Right v -> return (Right v)
-           Left se ->
-                case fromException se of
-                   Just ioe
-                    | isUserError ioe ->
-                       return (Left ioe)
-                   _ -> throw se
 \end{code}
 
 Standard signal handlers for catching ^C, which just throw an
@@ -196,18 +181,27 @@ installSignalHandlers.
 \begin{code}
 installSignalHandlers :: IO ()
 installSignalHandlers = do
+  main_thread <- myThreadId
+  modifyMVar_ interruptTargetThread (return . (main_thread :))
+
   let
-      interrupt_exn = (toException Interrupted)
+      interrupt_exn = (toException UserInterrupt)
 
       interrupt = do
        withMVar interruptTargetThread $ \targets ->
          case targets of
           [] -> return ()
           (thread:_) -> throwTo thread interrupt_exn
+
   --
 #if !defined(mingw32_HOST_OS)
-  installHandler sigQUIT (Catch interrupt) Nothing 
-  installHandler sigINT  (Catch interrupt) Nothing
+  _ <- installHandler sigQUIT  (Catch interrupt) Nothing 
+  _ <- installHandler sigINT   (Catch interrupt) Nothing
+  -- see #3656; in the future we should install these automatically for
+  -- all Haskell programs in the same way that we install a ^C handler.
+  let fatal_signal n = throwTo main_thread (Signal (fromIntegral n))
+  _ <- installHandler sigHUP   (Catch (fatal_signal sigHUP))  Nothing
+  _ <- installHandler sigTERM  (Catch (fatal_signal sigTERM)) Nothing
   return ()
 #else
   -- GHC 6.3+ has support for console events on Windows
@@ -219,7 +213,7 @@ installSignalHandlers = do
       sig_handler Break    = interrupt
       sig_handler _        = return ()
 
-  installHandler (Catch sig_handler)
+  _ <- installHandler (Catch sig_handler)
   return ()
 #endif