Commit eec29e91 authored by Iavor S. Diatchki's avatar Iavor S. Diatchki
Browse files

Merge remote-tracking branch 'origin/master' into type-nats

parents 588c08d7 e1f950f1
*.o
*.aux
*.hi
*.comp.stderr
*.comp.stdout
*.interp.stderr
*.interp.stdout
*.run.stderr
*.run.stdout
*.eventlog
*.genscript
# Specific generated files
/GNUmakefile
......@@ -11,3 +22,243 @@
/include/EventConfig.h
/include/HsBaseConfig.h
/include/HsBaseConfig.h.in
tests/.hpc/
tests/4006
tests/CPUTime001
tests/Concurrent/.hpc/
tests/Concurrent/4876
tests/Concurrent/ThreadDelay001
tests/IO/.hpc/
tests/IO/2122
tests/IO/2122-test
tests/IO/3307
tests/IO/4808
tests/IO/4808.test
tests/IO/4855
tests/IO/4895
tests/IO/IOError001
tests/IO/IOError002
tests/IO/T4144
tests/IO/chinese-file-*
tests/IO/chinese-name
tests/IO/concio002
tests/IO/countReaders001
tests/IO/countReaders001.txt
tests/IO/decodingerror001
tests/IO/decodingerror002
tests/IO/encoding001
tests/IO/encoding001.utf16
tests/IO/encoding001.utf16.utf16be
tests/IO/encoding001.utf16.utf16le
tests/IO/encoding001.utf16.utf32
tests/IO/encoding001.utf16.utf32be
tests/IO/encoding001.utf16.utf32le
tests/IO/encoding001.utf16.utf8
tests/IO/encoding001.utf16.utf8_bom
tests/IO/encoding001.utf16be
tests/IO/encoding001.utf16be.utf16
tests/IO/encoding001.utf16be.utf16le
tests/IO/encoding001.utf16be.utf32
tests/IO/encoding001.utf16be.utf32be
tests/IO/encoding001.utf16be.utf32le
tests/IO/encoding001.utf16be.utf8
tests/IO/encoding001.utf16be.utf8_bom
tests/IO/encoding001.utf16le
tests/IO/encoding001.utf16le.utf16
tests/IO/encoding001.utf16le.utf16be
tests/IO/encoding001.utf16le.utf32
tests/IO/encoding001.utf16le.utf32be
tests/IO/encoding001.utf16le.utf32le
tests/IO/encoding001.utf16le.utf8
tests/IO/encoding001.utf16le.utf8_bom
tests/IO/encoding001.utf32
tests/IO/encoding001.utf32.utf16
tests/IO/encoding001.utf32.utf16be
tests/IO/encoding001.utf32.utf16le
tests/IO/encoding001.utf32.utf32be
tests/IO/encoding001.utf32.utf32le
tests/IO/encoding001.utf32.utf8
tests/IO/encoding001.utf32.utf8_bom
tests/IO/encoding001.utf32be
tests/IO/encoding001.utf32be.utf16
tests/IO/encoding001.utf32be.utf16be
tests/IO/encoding001.utf32be.utf16le
tests/IO/encoding001.utf32be.utf32
tests/IO/encoding001.utf32be.utf32le
tests/IO/encoding001.utf32be.utf8
tests/IO/encoding001.utf32be.utf8_bom
tests/IO/encoding001.utf32le
tests/IO/encoding001.utf32le.utf16
tests/IO/encoding001.utf32le.utf16be
tests/IO/encoding001.utf32le.utf16le
tests/IO/encoding001.utf32le.utf32
tests/IO/encoding001.utf32le.utf32be
tests/IO/encoding001.utf32le.utf8
tests/IO/encoding001.utf32le.utf8_bom
tests/IO/encoding001.utf8
tests/IO/encoding001.utf8.utf16
tests/IO/encoding001.utf8.utf16be
tests/IO/encoding001.utf8.utf16le
tests/IO/encoding001.utf8.utf32
tests/IO/encoding001.utf8.utf32be
tests/IO/encoding001.utf8.utf32le
tests/IO/encoding001.utf8.utf8_bom
tests/IO/encoding001.utf8_bom
tests/IO/encoding001.utf8_bom.utf16
tests/IO/encoding001.utf8_bom.utf16be
tests/IO/encoding001.utf8_bom.utf16le
tests/IO/encoding001.utf8_bom.utf32
tests/IO/encoding001.utf8_bom.utf32be
tests/IO/encoding001.utf8_bom.utf32le
tests/IO/encoding001.utf8_bom.utf8
tests/IO/encoding002
tests/IO/encodingerror001
tests/IO/environment001
tests/IO/finalization001
tests/IO/hClose001
tests/IO/hClose001.tmp
tests/IO/hClose002
tests/IO/hClose002.tmp
tests/IO/hClose003
tests/IO/hDuplicateTo001
tests/IO/hFileSize001
tests/IO/hFileSize002
tests/IO/hFileSize002.out
tests/IO/hFlush001
tests/IO/hFlush001.out
tests/IO/hGetBuf001
tests/IO/hGetBuffering001
tests/IO/hGetChar001
tests/IO/hGetLine001
tests/IO/hGetLine002
tests/IO/hGetLine003
tests/IO/hGetPosn001
tests/IO/hGetPosn001.out
tests/IO/hIsEOF001
tests/IO/hIsEOF002
tests/IO/hIsEOF002.out
tests/IO/hReady001
tests/IO/hReady002
tests/IO/hSeek001
tests/IO/hSeek002
tests/IO/hSeek003
tests/IO/hSeek004
tests/IO/hSeek004.out
tests/IO/hSetBuffering002
tests/IO/hSetBuffering003
tests/IO/hSetBuffering004
tests/IO/hSetEncoding001
tests/IO/ioeGetErrorString001
tests/IO/ioeGetFileName001
tests/IO/ioeGetHandle001
tests/IO/isEOF001
tests/IO/misc001
tests/IO/misc001.out
tests/IO/newline001
tests/IO/newline001.out
tests/IO/openFile001
tests/IO/openFile002
tests/IO/openFile003
tests/IO/openFile004
tests/IO/openFile004.out
tests/IO/openFile005
tests/IO/openFile005.out1
tests/IO/openFile005.out2
tests/IO/openFile006
tests/IO/openFile006.out
tests/IO/openFile007
tests/IO/openFile007.out
tests/IO/openFile008
tests/IO/openTempFile001
tests/IO/putStr001
tests/IO/readFile001
tests/IO/readFile001.out
tests/IO/readwrite001
tests/IO/readwrite001.inout
tests/IO/readwrite002
tests/IO/readwrite002.inout
tests/IO/readwrite003
tests/IO/readwrite003.txt
tests/IO/tmp
tests/Numeric/.hpc/
tests/Numeric/num001
tests/Numeric/num002
tests/Numeric/num003
tests/Numeric/num004
tests/Numeric/num005
tests/Numeric/num006
tests/Numeric/num007
tests/Numeric/num008
tests/Numeric/num009
tests/Numeric/num010
tests/System/.hpc/
tests/System/exitWith001
tests/System/getArgs001
tests/System/getEnv001
tests/System/system001
tests/Text.Printf/.hpc/
tests/Text.Printf/1548
tests/addr001
tests/assert
tests/char001
tests/char002
tests/cstring001
tests/data-fixed-show-read
tests/dynamic001
tests/dynamic002
tests/dynamic003
tests/dynamic004
tests/dynamic005
tests/echo001
tests/enum01
tests/enum02
tests/enum03
tests/enum04
tests/enumDouble
tests/enumRatio
tests/exceptionsrun001
tests/exceptionsrun002
tests/fixed
tests/genericNegative001
tests/hGetBuf002
tests/hGetBuf003
tests/hPutBuf001
tests/hPutBuf002
tests/hPutBuf002.out
tests/hTell001
tests/hTell002
tests/hash001
tests/ioref001
tests/ix001
tests/length001
tests/lex001
tests/list001
tests/list002
tests/list003
tests/memo001
tests/memo002
tests/performGC001
tests/quotOverflow
tests/rand001
tests/ratio001
tests/readDouble001
tests/readFloat
tests/readInteger001
tests/readLitChar
tests/reads001
tests/show001
tests/showDouble
tests/stableptr001
tests/stableptr003
tests/stableptr004
tests/stableptr005
tests/take001
tests/tempfiles
tests/text001
tests/trace001
tests/tup001
tests/unicode001
tests/unicode002
tests/weak001
......@@ -23,7 +23,10 @@ module Data.IORef
readIORef, -- :: IORef a -> IO a
writeIORef, -- :: IORef a -> a -> IO ()
modifyIORef, -- :: IORef a -> (a -> a) -> IO ()
modifyIORef', -- :: IORef a -> (a -> a) -> IO ()
atomicModifyIORef, -- :: IORef a -> (a -> (a,b)) -> IO b
atomicModifyIORef', -- :: IORef a -> (a -> (a,b)) -> IO b
atomicWriteIORef,
#if !defined(__PARALLEL_HASKELL__) && defined(__GLASGOW_HASKELL__)
mkWeakIORef, -- :: IORef a -> IO () -> IO (Weak (IORef a))
......@@ -66,10 +69,28 @@ mkWeakIORef r@(IORef (STRef r#)) f = IO $ \s ->
case mkWeak# r# r f s of (# s1, w #) -> (# s1, Weak w #)
#endif
-- |Mutate the contents of an 'IORef'
-- |Mutate the contents of an 'IORef'.
--
-- Be warned that 'modifyIORef' does not apply the function strictly. This
-- means if the program calls 'modifyIORef' many times, but seldomly uses the
-- value, thunks will pile up in memory resulting in a space leak. This is a
-- common mistake made when using an IORef as a counter. For example, the
-- following will likely produce a stack overflow:
--
-- >ref <- newIORef 0
-- >replicateM_ 1000000 $ modifyIORef ref (+1)
-- >readIORef ref >>= print
--
-- To avoid this problem, use 'modifyIORef'' instead.
modifyIORef :: IORef a -> (a -> a) -> IO ()
modifyIORef ref f = readIORef ref >>= writeIORef ref . f
-- |Strict version of 'modifyIORef'
modifyIORef' :: IORef a -> (a -> a) -> IO ()
modifyIORef' ref f = do
x <- readIORef ref
let x' = f x
x' `seq` writeIORef ref x'
-- |Atomically modifies the contents of an 'IORef'.
--
......@@ -81,6 +102,15 @@ modifyIORef ref f = readIORef ref >>= writeIORef ref . f
-- is recommended that if you need to do anything more complicated
-- then using 'Control.Concurrent.MVar.MVar' instead is a good idea.
--
-- 'atomicModifyIORef' does not apply the function strictly. This is important
-- to know even if all you are doing is replacing the value. For example, this
-- will leak memory:
--
-- >ref <- newIORef '1'
-- >forever $ atomicModifyIORef ref (\_ -> ('2', ()))
--
-- Use 'atomicModifyIORef'' or 'atomicWriteIORef' to avoid this problem.
--
atomicModifyIORef :: IORef a -> (a -> (a,b)) -> IO b
#if defined(__GLASGOW_HASKELL__)
atomicModifyIORef = GHC.IORef.atomicModifyIORef
......@@ -99,6 +129,22 @@ atomicModifyIORef r f =
return b
#endif
-- | Strict version of 'atomicModifyIORef'. This forces both the value stored
-- in the 'IORef' as well as the value returned.
atomicModifyIORef' :: IORef a -> (a -> (a,b)) -> IO b
atomicModifyIORef' ref f = do
b <- atomicModifyIORef ref
(\x -> let (a, b) = f x
in (a, a `seq` b))
b `seq` return b
-- | Variant of 'writeIORef' with the \"barrier to reordering\" property that
-- 'atomicModifyIORef' has.
atomicWriteIORef :: IORef a -> a -> IO ()
atomicWriteIORef ref a = do
x <- atomicModifyIORef ref (\_ -> (a, ()))
x `seq` return ()
{- $memmodel
In a concurrent program, 'IORef' operations may appear out-of-order
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment