summaryrefslogtreecommitdiff
path: root/Control/Concurrent/Chan/Strict.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Control/Concurrent/Chan/Strict.hs')
-rw-r--r--Control/Concurrent/Chan/Strict.hs22
1 files changed, 14 insertions, 8 deletions
diff --git a/Control/Concurrent/Chan/Strict.hs b/Control/Concurrent/Chan/Strict.hs
index 52e4102..5aa184e 100644
--- a/Control/Concurrent/Chan/Strict.hs
+++ b/Control/Concurrent/Chan/Strict.hs
@@ -41,6 +41,7 @@ import Prelude
import System.IO.Unsafe ( unsafeInterleaveIO )
import Control.Concurrent.MVar.Strict
+import Control.Parallel.Strategies
-- A channel is represented by two @MVar@s keeping track of the two ends
-- of the channel contents,i.e., the read- and write ends. Empty @MVar@s
@@ -55,11 +56,16 @@ type Stream a = MVar (ChItem a)
data ChItem a = ChItem !a (Stream a)
+instance NFData (MVar a)
+
+instance NFData a => NFData (ChItem a) where
+ rnf (ChItem a s) = rnf a `seq` rnf s
+
-- @newChan@ sets up the read and write end of a channel by initialising
-- these two @MVar@s with an empty @MVar@.
-- |Build and returns a new instance of 'Chan'.
-newChan :: IO (Chan a)
+newChan :: NFData a => IO (Chan a)
newChan = do
hole <- newEmptyMVar
readm <- newMVar hole
@@ -72,7 +78,7 @@ newChan = do
-- new hole.
-- |Write a value to a 'Chan'.
-writeChan :: Chan a -> a -> IO ()
+writeChan :: NFData a => Chan a -> a -> IO ()
writeChan (Chan _read write) val = do
new_hole <- newEmptyMVar
modifyMVar_ write $ \old_hole -> do
@@ -80,7 +86,7 @@ writeChan (Chan _read write) val = do
return new_hole
-- |Read the next value from the 'Chan'.
-readChan :: Chan a -> IO a
+readChan :: NFData a => Chan a -> IO a
readChan (Chan readm _write) = do
modifyMVar readm $ \read_end -> do
(ChItem val new_read_end) <- readMVar read_end
@@ -92,14 +98,14 @@ readChan (Chan readm _write) = do
-- either channel from then on will be available from both. Hence this creates
-- a kind of broadcast channel, where data written by anyone is seen by
-- everyone else.
-dupChan :: Chan a -> IO (Chan a)
+dupChan :: NFData a => Chan a -> IO (Chan a)
dupChan (Chan _read write) = do
hole <- readMVar write
new_read <- newMVar hole
return (Chan new_read write)
-- |Put a data item back onto a channel, where it will be the next item read.
-unGetChan :: Chan a -> a -> IO ()
+unGetChan :: NFData a => Chan a -> a -> IO ()
unGetChan (Chan readm _write) val = do
new_read_end <- newEmptyMVar
modifyMVar_ readm $ \read_end -> do
@@ -107,7 +113,7 @@ unGetChan (Chan readm _write) val = do
return new_read_end
-- |Returns 'True' if the supplied 'Chan' is empty.
-isEmptyChan :: Chan a -> IO Bool
+isEmptyChan ::NFData a => Chan a -> IO Bool
isEmptyChan (Chan readm write) = do
withMVar readm $ \r -> do
w <- readMVar write
@@ -118,12 +124,12 @@ isEmptyChan (Chan readm write) = do
-- |Return a lazy list representing the contents of the supplied
-- 'Chan', much like 'System.IO.hGetContents'.
-getChanContents :: Chan a -> IO [a]
+getChanContents ::NFData a => Chan a -> IO [a]
getChanContents ch = unsafeInterleaveIO $ do
x <- readChan ch
xs <- getChanContents ch
return (x:xs)
-- |Write an entire list of items to a 'Chan'.
-writeList2Chan :: Chan a -> [a] -> IO ()
+writeList2Chan ::NFData a => Chan a -> [a] -> IO ()
writeList2Chan = mapM_ . writeChan