X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=inline;f=GHC%2FIOBase.lhs;h=6fa596a5c30f6e71b21c9ba62fadcaced75d842f;hb=e689c74ff37943db15ce9886f6361387a8f80e5f;hp=312fda9aaf7249c729f00d1ac994f94ee93750f4;hpb=dbe5ad2718b2133d8c4205589905cf14acd73dcf;p=ghc-base.git diff --git a/GHC/IOBase.lhs b/GHC/IOBase.lhs index 312fda9..6fa596a 100644 --- a/GHC/IOBase.lhs +++ b/GHC/IOBase.lhs @@ -112,7 +112,10 @@ returnIO x = IO (\ s -> (# s, x #)) -- --------------------------------------------------------------------------- -- Coercions between IO and ST ---stToIO :: (forall s. ST s a) -> IO a +-- | A monad transformer embedding strict state transformers in the 'IO' +-- monad. The 'RealWorld' parameter indicates that the internal state +-- used by the 'ST' computation is a special one supplied by the 'IO' +-- monad, and thus distinct from those used by invocations of 'runST'. stToIO :: ST RealWorld a -> IO a stToIO (ST m) = IO m @@ -164,7 +167,7 @@ It is less well known that > > main = do > writeIORef test [42] -> bang \<- readIORef test +> bang <- readIORef test > print (bang :: [Char]) This program will core dump. This problem with polymorphic references @@ -178,13 +181,19 @@ help of 'unsafePerformIO'. So be careful! unsafePerformIO :: IO a -> a unsafePerformIO (IO m) = case m realWorld# of (# _, r #) -> r +-- Why do we NOINLINE unsafePerformIO? See the comment with +-- GHC.ST.runST. Essentially the issue is that the IO computation +-- inside unsafePerformIO must be atomic: it must either all run, or +-- not at all. If we let the compiler see the application of the IO +-- to realWorld#, it might float out part of the IO. + {-| 'unsafeInterleaveIO' allows 'IO' computation to be deferred lazily. When passed a value of type @IO a@, the 'IO' will only be performed when the value of the @a@ is demanded. This is used to implement lazy file reading, see 'System.IO.hGetContents'. -} -{-# NOINLINE unsafeInterleaveIO #-} +{-# INLINE unsafeInterleaveIO #-} unsafeInterleaveIO :: IO a -> IO a unsafeInterleaveIO (IO m) = IO ( \ s -> let @@ -192,6 +201,10 @@ unsafeInterleaveIO (IO m) in (# s, r #)) +-- We believe that INLINE on unsafeInterleaveIO is safe, because the +-- state from this IO thread is passed explicitly to the interleaved +-- IO, so it cannot be floated out and shared. + -- --------------------------------------------------------------------------- -- Handle type @@ -396,7 +409,7 @@ type FilePath = String -- but not less frequently, than specified above. -- The output buffer is emptied as soon as it has been written out. -- --- Similarly, input occurs according to the buffer mode for handle {\em hdl}. +-- Similarly, input occurs according to the buffer mode for the handle: -- -- * /line-buffering/: when the buffer for the handle is not empty, -- the next item is obtained from the buffer; otherwise, when the @@ -408,8 +421,8 @@ type FilePath = String -- the next block of data is read into the buffer. -- -- * /no-buffering/: the next input item is read and returned. --- The 'hLookAhead' operation implies that even a no-buffered handle --- may require a one-character buffer. +-- The 'System.IO.hLookAhead' operation implies that even a no-buffered +-- handle may require a one-character buffer. -- -- The default buffering mode when a handle is opened is -- implementation-dependent and may depend on the file system object @@ -518,7 +531,8 @@ showHandle file = showString "{handle: " . showString file . showString "}" -- |The type of exceptions. Every kind of system-generated exception -- has a constructor in the 'Exception' type, and values of other -- types may be injected into 'Exception' by coercing them to --- 'Dynamic' (see the section on Dynamic Exceptions: "Control.Exception\#DynamicExceptions"). +-- 'Data.Dynamic.Dynamic' (see the section on Dynamic Exceptions: +-- "Control.Exception\#DynamicExceptions"). data Exception = ArithException ArithException -- ^Exceptions raised by arithmetic @@ -537,8 +551,8 @@ data Exception -- ^Asynchronous exceptions (see section on Asynchronous Exceptions: "Control.Exception\#AsynchronousExceptions"). | BlockedOnDeadMVar -- ^The current thread was executing a call to - -- 'takeMVar' that could never return, because there are no other - -- references to this 'MVar'. + -- 'Control.Concurrent.MVar.takeMVar' that could never return, + -- because there are no other references to this 'MVar'. | Deadlock -- ^There are no runnable threads, so the program is -- deadlocked. The 'Deadlock' exception is