907e9124b54500fd33f6197133810c3b85d43c89
[packages/base.git] / System / IO / Unsafe.hs
1 {-# LANGUAGE Unsafe #-}
2 {-# LANGUAGE CPP, NoImplicitPrelude #-}
3
4 -----------------------------------------------------------------------------
5 -- |
6 -- Module : System.IO.Unsafe
7 -- Copyright : (c) The University of Glasgow 2001
8 -- License : BSD-style (see the file libraries/base/LICENSE)
9 --
10 -- Maintainer : libraries@haskell.org
11 -- Stability : provisional
12 -- Portability : portable
13 --
14 -- \"Unsafe\" IO operations.
15 --
16 -----------------------------------------------------------------------------
17
18 module System.IO.Unsafe (
19 -- * Unsafe 'System.IO.IO' operations
20 unsafePerformIO,
21 unsafeDupablePerformIO,
22 unsafeInterleaveIO,
23 unsafeFixIO,
24 ) where
25
26 #ifdef __GLASGOW_HASKELL__
27 import GHC.Base
28 import GHC.IO
29 import GHC.IORef
30 import GHC.Exception
31 import Control.Exception
32 #endif
33
34 #ifdef __HUGS__
35 import Hugs.IOExts (unsafePerformIO, unsafeInterleaveIO)
36 unsafeDupablePerformIO = unsafePerformIO
37 #endif
38
39 -- | A slightly faster version of `System.IO.fixIO` that may not be
40 -- safe to use with multiple threads. The unsafety arises when used
41 -- like this:
42 --
43 -- > unsafeFixIO $ \r ->
44 -- > forkIO (print r)
45 -- > return (...)
46 --
47 -- In this case, the child thread will receive a @NonTermination@
48 -- exception instead of waiting for the value of @r@ to be computed.
49 --
50 unsafeFixIO :: (a -> IO a) -> IO a
51 unsafeFixIO k = do
52 ref <- newIORef (throw NonTermination)
53 ans <- unsafeDupableInterleaveIO (readIORef ref)
54 result <- k ans
55 writeIORef ref result
56 return result