unagi-chan-0.4.1.3: Fast concurrent queues with a Chan-like API, and more

Safe HaskellNone
LanguageHaskell2010

Control.Concurrent.Chan.Unagi.Bounded

Contents

Synopsis

Documentation

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 :: Int -> IO (InChan a, OutChan a) Source #

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.

data InChan a Source #

The write end of a channel created with newChan.

Instances
Eq (InChan a) Source # 
Instance details

Defined in Control.Concurrent.Chan.Unagi.Bounded.Internal

Methods

(==) :: InChan a -> InChan a -> Bool #

(/=) :: InChan a -> InChan a -> Bool #

data OutChan a Source #

The read end of a channel created with newChan.

Instances
Eq (OutChan a) Source # 
Instance details

Defined in Control.Concurrent.Chan.Unagi.Bounded.Internal

Methods

(==) :: OutChan a -> OutChan a -> Bool #

(/=) :: OutChan a -> OutChan a -> Bool #

Channel operations

Reading

readChan :: OutChan a -> IO a Source #

Read an element from the chan, blocking if the chan is empty.

Note re. exceptions: When an async exception is raised during a readChan the message that the read would have returned is likely to be lost, even when the read is known to be blocked on an empty queue. If you need to handle this scenario, you can use readChanOnException.

readChanOnException :: OutChan a -> (IO a -> IO ()) -> IO a Source #

Like readChan but allows recovery of the queue element which would have been read, in the case that an async exception is raised during the read. To be precise exceptions are raised, and the handler run, only when readChanOnException is blocking.

The second argument is a handler that takes a blocking IO action returning the element, and performs some recovery action. When the handler is called, the passed IO a is the only way to access the element.

tryReadChan :: OutChan a -> IO (Element a, IO a) Source #

Returns immediately with:

  • an Element a future, which returns one unique element when it becomes available via tryRead.
  • a blocking IO action that returns the element when it becomes available.

Note: This is a destructive operation. See Element for more details.

Note re. exceptions: When an async exception is raised during a tryReadChan the message that the read would have returned is likely to be lost, just as it would be when raised directly after this function returns.

newtype Element a Source #

An IO action that returns a particular enqueued element when and if it becomes available.

Each Element corresponds to a particular enqueued element, i.e. a returned Element always offers the only means to access one particular enqueued item. The value returned by tryRead moves monotonically from Nothing to Just a when and if an element becomes available, and is idempotent at that point.

So for instance:

   (in, out) <- newChan
   (el, _) <- tryReadChan out  -- READ FROM EMPTY CHAN
   writeChan in "msg1"
   writeChan in "msg2"
   readChan out        -- RETURNS "msg2"
   tryRead el          -- RETURNS "msg1" (which would otherwise be lost)

Constructors

Element 

Fields

Instances
Monad Element Source # 
Instance details

Defined in Control.Concurrent.Chan.Unagi.NoBlocking.Types

Methods

(>>=) :: Element a -> (a -> Element b) -> Element b #

(>>) :: Element a -> Element b -> Element b #

return :: a -> Element a #

fail :: String -> Element a #

Functor Element Source # 
Instance details

Defined in Control.Concurrent.Chan.Unagi.NoBlocking.Types

Methods

fmap :: (a -> b) -> Element a -> Element b #

(<$) :: a -> Element b -> Element a #

MonadFix Element Source # 
Instance details

Defined in Control.Concurrent.Chan.Unagi.NoBlocking.Types

Methods

mfix :: (a -> Element a) -> Element a #

MonadFail Element Source # 
Instance details

Defined in Control.Concurrent.Chan.Unagi.NoBlocking.Types

Methods

fail :: String -> Element a #

Applicative Element Source # 
Instance details

Defined in Control.Concurrent.Chan.Unagi.NoBlocking.Types

Methods

pure :: a -> Element a #

(<*>) :: Element (a -> b) -> Element a -> Element b #

liftA2 :: (a -> b -> c) -> Element a -> Element b -> Element c #

(*>) :: Element a -> Element b -> Element b #

(<*) :: Element a -> Element b -> Element a #

Alternative Element Source # 
Instance details

Defined in Control.Concurrent.Chan.Unagi.NoBlocking.Types

Methods

empty :: Element a #

(<|>) :: Element a -> Element a -> Element a #

some :: Element a -> Element [a] #

many :: Element a -> Element [a] #

MonadPlus Element Source # 
Instance details

Defined in Control.Concurrent.Chan.Unagi.NoBlocking.Types

Methods

mzero :: Element a #

mplus :: Element a -> Element a -> Element a #

getChanContents :: OutChan a -> IO [a] Source #

Return a lazy infinite list representing the contents of the supplied OutChan, much like System.IO.hGetContents.

estimatedLength :: InChan a -> IO Int Source #

Return the estimated length of a bounded queue

The more concurrent writes and reads that are happening, the more inaccurate the estimate of the chan's size is likely to be.

Writing

writeChan :: InChan a -> a -> IO () Source #

Write a value to the channel. If the chan is full this will block.

To be precise this may block when the number of elements in the queue >= size, and will certainly block when >= size*2, where size is the argument passed to newChan, rounded up to the next highest power of two.

Note re. exceptions: In the case that an async exception is raised while blocking here, the write will nonetheless succeed. When not blocking, exceptions are masked. Thus writes always succeed once writeChan is entered.

tryWriteChan :: InChan a -> a -> IO Bool Source #

Try to write a value to the channel, aborting if the write is likely to exceed the bounds, returning a Bool indicating whether the write was successful.

This function never blocks, but may occasionally write successfully to a queue that is already "full". Unlike writeChan this function treats the requested bounds (raised to nearest power of two) strictly, rather than using the n .. n*2 range. The more concurrent writes and reads that are happening, the more inaccurate the estimate of the chan's size is likely to be.

writeList2Chan :: InChan a -> [a] -> IO () Source #

Write an entire list of items to a chan type. Writes here from multiple threads may be interleaved, and infinite lists are supported.

Broadcasting

dupChan :: InChan a -> IO (OutChan a) Source #

Duplicate a chan: the returned OutChan begins empty, but data written to the argument InChan from then on will be available from both the original OutChan and the one returned here, creating a kind of broadcast channel.

Writers will be blocked only when the fastest reader falls behind the bounds; slower readers of duplicated OutChan may fall arbitrarily behind.