bracket_, -- :: IO a -> IO b -> IO c -> IO ()
finally, -- :: IO a -> IO b -> IO a
-
+
+#ifdef __GLASGOW_HASKELL__
+ setUncaughtExceptionHandler, -- :: (Exception -> IO ()) -> IO ()
+ getUncaughtExceptionHandler -- :: IO (Exception -> IO ())
+#endif
) where
#ifdef __GLASGOW_HASKELL__
import GHC.Base ( assert )
import GHC.Exception as ExceptionBase hiding (catch)
import GHC.Conc ( throwTo, ThreadId )
-import GHC.IOBase ( IO(..) )
+import GHC.IOBase ( IO(..), IORef(..), newIORef, readIORef, writeIORef )
+import GHC.Handle ( stdout, hFlush )
+import Foreign.C.String ( CString, withCStringLen )
#endif
#ifdef __HUGS__
assert True x = x
assert False _ = throw (AssertionFailed "")
#endif
+
+
+#ifdef __GLASGOW_HASKELL__
+{-# NOINLINE uncaughtExceptionHandler #-}
+uncaughtExceptionHandler :: IORef (Exception -> IO ())
+uncaughtExceptionHandler = unsafePerformIO (newIORef defaultHandler)
+ where
+ defaultHandler :: Exception -> IO ()
+ defaultHandler ex = do
+ (hFlush stdout) `catchException` (\ _ -> return ())
+ let msg = case ex of
+ Deadlock -> "no threads to run: infinite loop or deadlock?"
+ ErrorCall s -> s
+ other -> showsPrec 0 other "\n"
+ withCStringLen ("Fail: "++msg) $ \(cstr,len) -> writeErrString cstr len
+
+foreign import ccall unsafe "writeErrString__"
+ writeErrString :: CString -> Int -> IO ()
+
+setUncaughtExceptionHandler :: (Exception -> IO ()) -> IO ()
+setUncaughtExceptionHandler = writeIORef uncaughtExceptionHandler
+
+getUncaughtExceptionHandler :: IO (Exception -> IO ())
+getUncaughtExceptionHandler = readIORef uncaughtExceptionHandler
+#endif