{-# LANGUAGE Unsafe #-}
{-# LANGUAGE NoImplicitPrelude #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  System.IO.Unsafe
-- Copyright   :  (c) The University of Glasgow 2001
-- License     :  BSD-style (see the file libraries/base/LICENSE)
-- 
-- Maintainer  :  libraries@haskell.org
-- Stability   :  provisional
-- Portability :  portable
--
-- \"Unsafe\" IO operations.
--
-----------------------------------------------------------------------------

module System.IO.Unsafe (
   -- * Unsafe 'System.IO.IO' operations
   unsafePerformIO,
   unsafeDupablePerformIO,
   unsafeInterleaveIO,
   unsafeFixIO,
  ) where

import GHC.Base
import GHC.IO
import GHC.IORef
import GHC.Exception
import Control.Exception

-- | A slightly faster version of `System.IO.fixIO` that may not be
-- safe to use with multiple threads.  The unsafety arises when used
-- like this:
--
-- >  unsafeFixIO $ \r -> do
-- >     forkIO (print r)
-- >     return (...)
--
-- In this case, the child thread will receive a @NonTermination@
-- exception instead of waiting for the value of @r@ to be computed.
--
-- @since 4.5.0.0
unsafeFixIO :: (a -> IO a) -> IO a
unsafeFixIO :: forall a. (a -> IO a) -> IO a
unsafeFixIO a -> IO a
k = do
  IORef a
ref <- a -> IO (IORef a)
forall a. a -> IO (IORef a)
newIORef (NonTermination -> a
forall a e. Exception e => e -> a
throw NonTermination
NonTermination)
  a
ans <- IO a -> IO a
forall a. IO a -> IO a
unsafeDupableInterleaveIO (IORef a -> IO a
forall a. IORef a -> IO a
readIORef IORef a
ref)
  a
result <- a -> IO a
k a
ans
  IORef a -> a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef a
ref a
result
  a -> IO a
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
result