content: {-# LANGUAGE CPP #-}
  module Control.Concurrent.Chan.Unagi.Bounded
  #ifdef NOT_optimised
      {-# WARNING "This library is unlikely to perform well on architectures other than i386/x64/aarch64" #-}
  #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
      , estimatedLength
      -- ** 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 infinite 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)
  