Portability | Requires STM |
---|---|
Maintainer | joeyadams3.14159@gmail.com |
Safe Haskell | Safe-Infered |
FIFO queue for STM, bounded by the total "size" of the items.
- data SBChan a
- newSBChan :: Int -> STM (SBChan a)
- newSBChanIO :: Int -> IO (SBChan a)
- class ItemSize a where
- newtype SBCItem a = SBCItem {
- unSBCItem :: a
- readSBChan :: ItemSize a => SBChan a -> STM a
- writeSBChan :: ItemSize a => SBChan a -> a -> STM ()
- peekSBChan :: SBChan a -> STM a
- unGetSBChan :: ItemSize a => SBChan a -> a -> STM ()
- isEmptySBChan :: SBChan a -> STM Bool
- tryReadSBChan :: ItemSize a => SBChan a -> STM (Maybe a)
- tryWriteSBChan :: ItemSize a => SBChan a -> a -> STM Bool
- tryPeekSBChan :: SBChan a -> STM (Maybe a)
- cramSBChan :: ItemSize a => SBChan a -> a -> STM ()
- rollSBChan :: ItemSize a => SBChan a -> a -> STM Int
- getLimitSBChan :: SBChan a -> STM Int
- setLimitSBChan :: SBChan a -> Int -> STM ()
- satisfyLimitSBChan :: ItemSize a => SBChan a -> STM Int
- clearSBChan :: SBChan a -> STM ()
SBChan
newSBChan :: Int -> STM (SBChan a)Source
Create a new, empty SBChan
, with the given size limit.
To change the size limit later, use setLimitSBChan
.
newSBChanIO :: Int -> IO (SBChan a)Source
IO
variant of newSBChan
. This is useful for creating top-level
SBChan
s using unsafePerformIO
, because performing
atomically
inside a pure computation is extremely dangerous (can lead to
NestedAtomically
errors and even segfaults,
see GHC ticket #5866).
Example:
logChannel ::SBChan
LogEntry logChannel =unsafePerformIO
(newSBChanIO
500000) {-# NOINLINE logChannel #-}
Item sizes
Reading and writing
readSBChan :: ItemSize a => SBChan a -> STM aSource
Read the next item from the channel. retry
if the channel is empty.
writeSBChan :: ItemSize a => SBChan a -> a -> STM ()Source
Write an item to the channel. retry
if the item does not fit.
As an exception, if the channel is currently empty, but the item's size exceeds the channel limit all by itself, it will be written to the channel anyway. This is to prevent a large item from causing the application to deadlock.
peekSBChan :: SBChan a -> STM aSource
Get the next item from the channel without removing it. retry
if the
channel is empty.
unGetSBChan :: ItemSize a => SBChan a -> a -> STM ()Source
Put an item back on the channel, where it will be the next item read.
This will always succeed, even if it causes the channel's size limit to be
exceeded. The rationale is that the size limit can be exceeded in some
cases (e.g. by writing an oversized item to an empty channel). If we allow
writeSBChan
to exceed the limit, but don't allow unGetSBChan
to exceed
the limit, then we can't always read an item and put it back.
Note that unGetTBQueue
in
Control.Concurrent.STM.TBQueue is different: it will retry
if the queue
is full.
Non-blocking variants
tryReadSBChan :: ItemSize a => SBChan a -> STM (Maybe a)Source
Variant of readSBChan
which does not retry
. Instead, it returns
Nothing
if the channel is empty.
tryWriteSBChan :: ItemSize a => SBChan a -> a -> STM BoolSource
Variant of writeSBChan
which does not retry
. Instead, it returns
False
if the item does not fit.
tryPeekSBChan :: SBChan a -> STM (Maybe a)Source
Variant of peekSBChan
which does not retry
. Instead, it returns
Nothing
if the channel is empty.
Alternative overflow strategies
cramSBChan :: ItemSize a => SBChan a -> a -> STM ()Source
Like writeSBChan
, but ignore the channel size limit. This will always
succeed, and will not retry
.
rollSBChan :: ItemSize a => SBChan a -> a -> STM IntSource
Like writeSBChan
, but if the channel is full, drop items from the
beginning of the channel until there is enough room for the new item
(or until the channel is empty). This will always succeed, and will not
retry
.
Return the number of items dropped.
Managing the limit
getLimitSBChan :: SBChan a -> STM IntSource
Get the current limit on total size of items in the channel.
setLimitSBChan :: SBChan a -> Int -> STM ()Source
Set the total size limit. If the channel exceeds the new limit, too bad.
satisfyLimitSBChan :: ItemSize a => SBChan a -> STM IntSource
Drop items from the beginning of the channel until the channel's size limit is satisfied, or until there is only one item left in the channel.
Return the number of items dropped.