Don't use "deriving Typeable" (for portability reasons)
[ghc-base.git] / System / Timeout.hs
index c7e4ee2..0e82704 100644 (file)
@@ -1,4 +1,3 @@
-{-# OPTIONS -fglasgow-exts #-}
 -------------------------------------------------------------------------------
 -- |
 -- Module      :  System.Timeout
@@ -13,6 +12,8 @@
 --
 -------------------------------------------------------------------------------
 
+#include "Typeable.h"
+
 module System.Timeout ( timeout ) where
 
 #if __NHC__
@@ -20,19 +21,27 @@ timeout :: Int -> IO a -> IO (Maybe a)
 timeout n f = fmap Just f
 #else
 
-import Prelude             (IO, Ord((<)), Eq((==)), Int, (.), otherwise, fmap)
+import Prelude             (Show(show), IO, Ord((<)), Eq((==)), Int,
+                            (.), otherwise, fmap)
 import Data.Maybe          (Maybe(..))
 import Control.Monad       (Monad(..), guard)
 import Control.Concurrent  (forkIO, threadDelay, myThreadId, killThread)
-import Control.Exception   (handleJust, throwDynTo, dynExceptions, bracket)
+import Control.Exception   (Exception, handleJust, throwTo, bracket)
 import Data.Dynamic        (Typeable, fromDynamic)
+import Data.Typeable
 import Data.Unique         (Unique, newUnique)
 
 -- An internal type that is thrown as a dynamic exception to
 -- interrupt the running IO computation when the timeout has
 -- expired.
 
-data Timeout = Timeout Unique deriving (Eq, Typeable)
+data Timeout = Timeout Unique deriving Eq
+INSTANCE_TYPEABLE0(Timeout,timeoutTc,"Timeout")
+
+instance Show Timeout where
+    show _ = "<<timeout>>"
+
+instance Exception Timeout
 
 -- |Wrap an 'IO' computation to time out and return @Nothing@ in case no result
 -- is available within @n@ microseconds (@1\/10^6@ seconds). In case a result
@@ -57,7 +66,7 @@ data Timeout = Timeout Unique deriving (Eq, Typeable)
 -- blocks, no timeout event can be delivered until the FFI call returns, which
 -- pretty much negates the purpose of the combinator. In practice, however,
 -- this limitation is less severe than it may sound. Standard I\/O functions
--- like 'System.IO.hGetBuf', 'System.IO.hPutBuf', 'Network.Socket.accept', or
+-- like 'System.IO.hGetBuf', 'System.IO.hPutBuf', Network.Socket.accept, or
 -- 'System.IO.hWaitForInput' appear to be blocking, but they really don't
 -- because the runtime system uses scheduling mechanisms like @select(2)@ to
 -- perform asynchronous I\/O, so it is possible to interrupt standard socket
@@ -70,9 +79,9 @@ timeout n f
     | otherwise = do
         pid <- myThreadId
         ex  <- fmap Timeout newUnique
-        handleJust (\e -> dynExceptions e >>= fromDynamic >>= guard . (ex ==))
+        handleJust (\e -> if e == ex then Just () else Nothing)
                    (\_ -> return Nothing)
-                   (bracket (forkIO (threadDelay n >> throwDynTo pid ex))
+                   (bracket (forkIO (threadDelay n >> throwTo pid ex))
                             (killThread)
                             (\_ -> fmap Just f))
 #endif