Copyright | (c) Justus Adam 2016 |
---|---|
License | BSD3 |
Maintainer | dev@justus.science |
Stability | experimental |
Portability | POSIX |
Safe Haskell | None |
Language | Haskell2010 |
- type Mutable v = IORef v
- newMutable :: MonadIO m => a -> m (Mutable a)
- readMutable :: MonadIO m => Mutable a -> m a
- writeMutable :: MonadIO m => Mutable a -> a -> m ()
- modifyMutable :: MonadIO m => Mutable a -> (a -> a) -> m ()
- type Synchronized = MVar
- readSynchronized :: MonadIO m => Synchronized a -> m a
- tryReadSynchronized :: MonadIO m => Synchronized a -> m (Maybe a)
- takeSynchronized :: MonadIO m => Synchronized a -> m a
- tryTakeSynchronized :: MonadIO m => Synchronized a -> m (Maybe a)
- writeSynchronized :: MonadIO m => Synchronized a -> a -> m ()
- tryWriteSynchronized :: MonadIO m => Synchronized a -> a -> m Bool
- isEmptySynchronized :: MonadIO m => Synchronized a -> m Bool
Documentation
type Mutable v = IORef v Source #
A mutable reference to a value of type v
This is like a pointer in c, the value behind which can be mutated by several functions. So long as they retain this reference they are able to retrieve the updated value.
newMutable :: MonadIO m => a -> m (Mutable a) Source #
Create a new mutable reference of type v
from an initial value.
readMutable :: MonadIO m => Mutable a -> m a Source #
Retrieve the value behind by a mutable reference.
writeMutable :: MonadIO m => Mutable a -> a -> m () Source #
Set the value inside a mutable reference.
modifyMutable :: MonadIO m => Mutable a -> (a -> a) -> m () Source #
Change the value behind a mutable reference.
type Synchronized = MVar Source #
A value that can be shared on multiple concurrent Threads.
This value works like a channel. It can either be empty or full.
If it is empty writeSynchronized
fills it, otherwise the write blocks.
If it is full takeSynchronized
empties, otherwise it blocks until it is filled.
readSynchronized
does not empty it and also blocks if the Synchronized
is empty.
Should you just use it as a thread safe mutable variable, mutations typically follow the pattern:
val <- takeSynchronized -- obtain the value and leave it empty to block concurrent reads
let mod = modify val -- modify the value
writeSynchronized mod -- write back the result
Another use for this type is as a message channel, where we have a producer and a consumer,
the producer tries to write values into the Synchronized
(writeSynchronized
) and the consumer
waits for the Synchronized
to be filled and takes the value takeSynchronized
for procesing.
It works generally best if any Synchronized
is only used for one of these two applications at the same time.
This type is the same as MVar
, only renamed for readability. If you want a more in depth documentation, see the documentation for MVar
.
readSynchronized :: MonadIO m => Synchronized a -> m a Source #
Read the vaue, but don't empty the Synchronized
. Blocks if it is empty.
tryReadSynchronized :: MonadIO m => Synchronized a -> m (Maybe a) Source #
Non blocking version of readSynchronized
. Returns Nothing
if it was empty.
takeSynchronized :: MonadIO m => Synchronized a -> m a Source #
Read the value and empty the Synchronized
, blocks if already empty.
tryTakeSynchronized :: MonadIO m => Synchronized a -> m (Maybe a) Source #
Non blocking version of takeSynchronized
, returns Nothing
if it was empty.
writeSynchronized :: MonadIO m => Synchronized a -> a -> m () Source #
Fills the empty Synchronized
with a value, blocks if it is full.
tryWriteSynchronized :: MonadIO m => Synchronized a -> a -> m Bool Source #
Non blocking version of writeSynchronized
. Returns False
if it was full.
isEmptySynchronized :: MonadIO m => Synchronized a -> m Bool Source #
Query if the Synchronized
is empty or full.