TopHandler now uses the new extensible exceptions
authorIan Lynagh <igloo@earth.li>
Thu, 31 Jul 2008 15:35:53 +0000 (15:35 +0000)
committerIan Lynagh <igloo@earth.li>
Thu, 31 Jul 2008 15:35:53 +0000 (15:35 +0000)
GHC/Conc.lhs
GHC/TopHandler.lhs
GHC/TopHandler.lhs-boot

index e6197d9..1b61036 100644 (file)
@@ -111,7 +111,7 @@ import {-# SOURCE #-} GHC.TopHandler ( reportError, reportStackOverflow )
 import Data.Maybe
 
 import GHC.Base
-import GHC.IOBase hiding ( Exception, BlockedOnDeadMVar, BlockedIndefinitely )
+import GHC.IOBase
 import GHC.Num          ( Num(..) )
 import GHC.Real         ( fromIntegral, div )
 #ifndef mingw32_HOST_OS
@@ -121,13 +121,12 @@ import GHC.Base         ( Int(..) )
 import GHC.Read         ( Read )
 import GHC.Enum         ( Enum )
 #endif
-import GHC.Exception    ( throw )
+import GHC.Exception    ( SomeException(..), throw )
 import GHC.Pack         ( packCString# )
 import GHC.Ptr          ( Ptr(..), plusPtr, FunPtr(..) )
 import GHC.STRef
 import GHC.Show         ( Show(..), showString )
 import Data.Typeable
-import Control.OldException hiding (throwTo)
 
 infixr 0 `par`, `pseq`
 \end{code}
@@ -237,20 +236,22 @@ numCapabilities = unsafePerformIO $  do
 
 foreign import ccall "&n_capabilities" n_capabilities :: Ptr CInt
 
-childHandler :: Exception -> IO ()
+childHandler :: SomeException -> IO ()
 childHandler err = catchException (real_handler err) childHandler
 
-real_handler :: Exception -> IO ()
-real_handler ex =
-  case ex of
-        -- ignore thread GC and killThread exceptions:
-        BlockedOnDeadMVar            -> return ()
-        BlockedIndefinitely          -> return ()
-        AsyncException ThreadKilled  -> return ()
-
-        -- report all others:
-        AsyncException StackOverflow -> reportStackOverflow
-        other       -> reportError other
+real_handler :: SomeException -> IO ()
+real_handler se@(SomeException ex) =
+  -- ignore thread GC and killThread exceptions:
+  case cast ex of
+  Just BlockedOnDeadMVar                -> return ()
+  _ -> case cast ex of
+       Just BlockedIndefinitely         -> return ()
+       _ -> case cast ex of
+            Just ThreadKilled           -> return ()
+            _ -> case cast ex of
+                 -- report all others:
+                 Just StackOverflow     -> reportStackOverflow
+                 _                      -> reportError se
 
 {- | 'killThread' terminates the given thread (GHC only).
 Any work already done by the thread isn\'t
@@ -263,7 +264,7 @@ terms of 'throwTo':
 
 -}
 killThread :: ThreadId -> IO ()
-killThread tid = throwTo tid (AsyncException ThreadKilled)
+killThread tid = throwTo tid (toException ThreadKilled)
 
 {- | 'throwTo' raises an arbitrary exception in the target thread (GHC only).
 
@@ -296,7 +297,7 @@ a pending 'throwTo'.  This is arguably undesirable behaviour.
 
  -}
 -- XXX This is duplicated in Control.{Old,}Exception
-throwTo :: ThreadId -> Exception -> IO ()
+throwTo :: ThreadId -> SomeException -> IO ()
 throwTo (ThreadId id) ex = IO $ \ s ->
    case (killThread# id ex s) of s1 -> (# s1, () #)
 
@@ -495,7 +496,7 @@ orElse :: STM a -> STM a -> STM a
 orElse (STM m) e = STM $ \s -> catchRetry# m (unSTM e) s
 
 -- |Exception handling within STM actions.
-catchSTM :: STM a -> (Exception -> STM a) -> STM a
+catchSTM :: STM a -> (SomeException -> STM a) -> STM a
 catchSTM (STM m) k = STM $ \s -> catchSTM# m (\ex -> unSTM (k ex)) s
 
 -- | Low-level primitive on which always and alwaysSucceeds are built.
index e2da473..236f5ff 100644 (file)
@@ -25,7 +25,7 @@ module GHC.TopHandler (
 
 #include "HsBaseConfig.h"
 
-import Control.OldException as Old
+import Control.Exception
 import Data.Maybe
 import Control.Concurrent.MVar
 
@@ -37,8 +37,9 @@ import GHC.Err
 import GHC.Num
 import GHC.Real
 import {-# SOURCE #-} GHC.Handle
-import GHC.IOBase hiding (Exception)
+import GHC.IOBase
 import GHC.Weak
+import Data.Typeable
 
 -- | 'runMainIO' is wrapped around 'Main.main' (or whatever main is
 -- called in the program).  It catches otherwise uncaught exceptions,
@@ -52,11 +53,11 @@ runMainIO main =
            m <- deRefWeak weak_tid 
            case m of
                Nothing  -> return ()
-               Just tid -> throwTo tid (AsyncException UserInterrupt)
+               Just tid -> throwTo tid (toException UserInterrupt)
       a <- main
       cleanUp
       return a
-    `Old.catch`
+    `catch`
       topHandler
 
 install_interrupt_handler :: IO () -> IO ()
@@ -107,7 +108,7 @@ mkWeakThreadId t@(ThreadId t#) = IO $ \s ->
 -- program.
 --
 runIO :: IO a -> IO a
-runIO main = Old.catch main topHandler
+runIO main = catch main topHandler
 
 -- | Like 'runIO', but in the event of an exception that causes an exit,
 -- we don't shut down the system cleanly, we just exit.  This is
@@ -122,7 +123,7 @@ runIO main = Old.catch main topHandler
 -- safeExit.  There is a race to shut down between the main and child threads.
 --
 runIOFastExit :: IO a -> IO a
-runIOFastExit main = Old.catch main topHandlerFastExit
+runIOFastExit main = catch main topHandlerFastExit
         -- NB. this is used by the testsuite driver
 
 -- | The same as 'runIO', but for non-IO computations.  Used for
@@ -130,12 +131,12 @@ runIOFastExit main = Old.catch main topHandlerFastExit
 -- are used to export Haskell functions with non-IO types.
 --
 runNonIO :: a -> IO a
-runNonIO a = Old.catch (a `seq` return a) topHandler
+runNonIO a = catch (a `seq` return a) topHandler
 
-topHandler :: Exception -> IO a
-topHandler err = Old.catch (real_handler safeExit err) topHandler
+topHandler :: SomeException -> IO a
+topHandler err = catch (real_handler safeExit err) topHandler
 
-topHandlerFastExit :: Exception -> IO a
+topHandlerFastExit :: SomeException -> IO a
 topHandlerFastExit err = 
   catchException (real_handler fastExit err) topHandlerFastExit
 
@@ -143,29 +144,29 @@ topHandlerFastExit err =
 -- (e.g. evaluating the string passed to 'error' might generate
 --  another error, etc.)
 --
-real_handler :: (Int -> IO a) -> Exception -> IO a
-real_handler exit exn =
+real_handler :: (Int -> IO a) -> SomeException -> IO a
+real_handler exit se@(SomeException exn) =
   cleanUp >>
-  case exn of
-        AsyncException StackOverflow -> do
+  case cast exn of
+      Just StackOverflow -> do
            reportStackOverflow
            exit 2
 
-        AsyncException UserInterrupt  -> exitInterrupted
+      Just UserInterrupt  -> exitInterrupted
 
-        -- only the main thread gets ExitException exceptions
-        ExitException ExitSuccess     -> exit 0
-        ExitException (ExitFailure n) -> exit n
+      _ -> case cast exn of
+           -- only the main thread gets ExitException exceptions
+           Just ExitSuccess     -> exit 0
+           Just (ExitFailure n) -> exit n
 
-        other -> do
-           reportError other
-           exit 1
+           _ -> do reportError se
+                   exit 1
            
 
 reportStackOverflow :: IO a
 reportStackOverflow = do callStackOverflowHook; return undefined
 
-reportError :: Exception -> IO a
+reportError :: SomeException -> IO a
 reportError ex = do
    handler <- getUncaughtExceptionHandler
    handler ex
index 3c5fb1b..8a5304b 100644 (file)
@@ -3,8 +3,8 @@
 module GHC.TopHandler ( reportError, reportStackOverflow ) where
 
 import GHC.IOBase (IO)
-import Control.OldException (Exception)
+import Control.Exception (SomeException)
 
-reportError :: Exception -> IO a
+reportError :: SomeException -> IO a
 reportStackOverflow :: IO a
 \end{code}