unagi-chan-0.3.0.2: src/Control/Concurrent/Chan/Unagi/Bounded.hs
{-# 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)