Data.Primitive.MVar

primitive-0.9.0.0: Primitive memory-related operations

License | BSD2
Portability | non-portable
Safe Haskell | None
Language | Haskell2010

Data.Primitive.MVar

Description

Primitive operations on `MVar`. This module provides a similar interface to Control.Concurrent.MVar. However, the functions are generalized to work in any `PrimMonad` instead of only working in `IO`. Note that all of the functions here are completely deterministic. Users of `MVar` are responsible for designing abstractions that guarantee determinism in the presence of multi-threading.

For a more detailed explanation, see Control.Concurrent.MVar.

Since: 0.6.4.0

Synopsis

- data MVar s a = MVar (MVar# s a)
- newMVar :: PrimMonad m => a -> m (MVar (PrimState m) a)
- isEmptyMVar :: PrimMonad m => MVar (PrimState m) a -> m Bool
- newEmptyMVar :: PrimMonad m => m (MVar (PrimState m) a)
- putMVar :: PrimMonad m => MVar (PrimState m) a -> a -> m ()
- readMVar :: PrimMonad m => MVar (PrimState m) a -> m a
- takeMVar :: PrimMonad m => MVar (PrimState m) a -> m a
- tryPutMVar :: PrimMonad m => MVar (PrimState m) a -> a -> m Bool
- tryReadMVar :: PrimMonad m => MVar (PrimState m) a -> m (Maybe a)
- tryTakeMVar :: PrimMonad m => MVar (PrimState m) a -> m (Maybe a)

# Documentation

data MVar s a #

A synchronizing variable, used for communication between concurrent threads. It can be thought of as a box, which may be empty or full.

Constructors

MVar (MVar# s a) |

#### Instances

Instances details

Eq (MVar s a) # |
Instance details Defined in Data.Primitive.MVar Methods (==) :: MVar s a -> MVar s a -> Bool # (/=) :: MVar s a -> MVar s a -> Bool #

newMVar :: PrimMonad m => a -> m (MVar (PrimState m) a) #

Create a new `MVar` that holds the supplied argument.

isEmptyMVar :: PrimMonad m => MVar (PrimState m) a -> m Bool #

Check whether a given `MVar` is empty.

Notice that the boolean value returned is just a snapshot of the state of the `MVar`. By the time you get to react on its result, the `MVar` may have been filled (or emptied) - so be extremely careful when using this operation. Use `tryTakeMVar` instead if possible.

newEmptyMVar :: PrimMonad m => m (MVar (PrimState m) a) #

Create a new `MVar` that is initially empty.

putMVar :: PrimMonad m => MVar (PrimState m) a -> a -> m () #

Put a value into an `MVar`. If the `MVar` is currently full, `putMVar` will wait until it becomes empty.

There are two further important properties of `putMVar`:

- `putMVar` is single-wakeup. That is, if there are multiple threads blocked in `putMVar`, and the `MVar` becomes empty, only one thread will be woken up. The runtime guarantees that the woken thread completes its `putMVar` operation.
- When multiple threads are blocked on an `MVar`, they are woken up in FIFO order. This is useful for providing fairness properties of abstractions built using `MVar`s.

readMVar :: PrimMonad m => MVar (PrimState m) a -> m a #

Atomically read the contents of an `MVar`. If the `MVar` is currently empty, `readMVar` will wait until it is full. `readMVar` is guaranteed to receive the next `putMVar`.

Multiple Wakeup: `readMVar` is multiple-wakeup, so when multiple readers are blocked on an `MVar`, all of them are woken up at the same time.

- It is single-wakeup instead of multiple-wakeup.
- It might not receive the value from the next call to `putMVar` if there is already a pending thread blocked on `takeMVar`.
- If another thread puts a value in the `MVar` in between the calls to `takeMVar` and `putMVar`, that value may be overridden.

takeMVar :: PrimMonad m => MVar (PrimState m) a -> m a #

Return the contents of the `MVar`. If the `MVar` is currently empty, `takeMVar` will wait until it is full. After a `takeMVar`, the `MVar` is left empty.

There are two further important properties of `takeMVar`:

- `takeMVar` is single-wakeup. That is, if there are multiple threads blocked in `takeMVar`, and the `MVar` becomes full, only one thread will be woken up. The runtime guarantees that the woken thread completes its `takeMVar` operation.
- When multiple threads are blocked on an `MVar`, they are woken up in FIFO order. This is useful for providing fairness properties of abstractions built using `MVar`s.

tryPutMVar :: PrimMonad m => MVar (PrimState m) a -> a -> m Bool #

A non-blocking version of `putMVar`. The `tryPutMVar` function attempts to put the value `a` into the `MVar`, returning `True` if it was successful, or `False` otherwise.

tryReadMVar :: PrimMonad m => MVar (PrimState m) a -> m (Maybe a) #

A non-blocking version of `readMVar`. The `tryReadMVar` function returns immediately, with `Nothing` if the `MVar` was empty, or ``Just` a` if the `MVar` was full with contents `a`.

- It is single-wakeup instead of multiple-wakeup.
- In the presence of other threads calling `putMVar`, `tryReadMVar` may block.
- If another thread puts a value in the `MVar` in between the calls to `tryTakeMVar` and `putMVar`, that value may be overridden.

tryTakeMVar :: PrimMonad m => MVar (PrimState m) a -> m (Maybe a) #

A non-blocking version of `takeMVar`. The `tryTakeMVar` function returns immediately, with `Nothing` if the `MVar` was empty, or ``Just` a` if the `MVar` was full with contents `a`. After `tryTakeMVar`, the `MVar` is left empty.