{-# LANGUAGE CPP #-} module Control.Concurrent.Chan.Unagi.Bounded #ifdef NOT_x86 {-# WARNING "This library is unlikely to perform well on architectures without a fetch-and-add instruction" #-} #endif #if __GLASGOW_HASKELL__ < 708 {-# WARNING "Waking up blocked writers may be slower than desired in GHC<7.8 which makes readMVar non-blocking on full MVars. Nextidering upgrading." #-} #endif ( {- | A queue with bounded size, which supports a 'writeChan' which blocks when the number of messages grows larger than desired. The bounds are maintained loosely between @n@ and @n*2@; see the caveats and descriptions of semantics in 'readChan' and 'writeChan' for details. -} -- * Creating channels newChan , InChan(), OutChan() -- * Channel operations -- ** Reading , readChan , readChanOnException , tryReadChan , Element(..) , getChanContents -- ** Writing , writeChan , tryWriteChan , writeList2Chan -- ** Broadcasting , dupChan ) where -- forked from src/Control/Concurrent/Chan/Unagi.hs 43706b2 import Control.Concurrent.Chan.Unagi.Bounded.Internal import Control.Concurrent.Chan.Unagi.NoBlocking.Types -- For 'writeList2Chan', as in vanilla Chan import System.IO.Unsafe ( unsafeInterleaveIO ) -- | Create a new channel of the passed size, returning its write and read ends. -- -- The passed integer bounds will be rounded up to the next highest power of -- two, @n@. The queue may grow up to size @2*n@ (see 'writeChan' for details), -- and the resulting chan pair requires O(n) space. newChan :: Int -> IO (InChan a, OutChan a) newChan size = newChanStarting (maxBound - 10) size -- lets us test counter overflow in tests and normal course of operation -- | Return a lazy list representing the contents of the supplied OutChan, much -- like System.IO.hGetContents. getChanContents :: OutChan a -> IO [a] getChanContents ch = unsafeInterleaveIO (do x <- unsafeInterleaveIO $ readChan ch xs <- getChanContents ch return (x:xs) ) -- | Write an entire list of items to a chan type. Writes here from multiple -- threads may be interleaved, and infinite lists are supported. writeList2Chan :: InChan a -> [a] -> IO () {-# INLINABLE writeList2Chan #-} writeList2Chan ch = sequence_ . map (writeChan ch)