Safe Haskell | Trustworthy |
---|---|
Language | Haskell98 |
This module implements labeled MVar
s. The interface is analogous to
Control.Concurrent.MVar, but the operations take place in the LIO
monad. A labeled MVar, of type
, is a mutable location
that can be in one of two states; an LMVar
l aLMVar
can be empty, or it can
be full (with a value of type a
). The location is protected by a
label of type l
. As in the case of LIORef
s (see LIO.LIORef),
this label is fixed and does not change according to the content
placed into the location. Unlike LIORef
s, most operations use
guardWrite
or guardWriteP
, reflecting the fact that there is no
such thing as read-only or write-only operations on an LMVar
.
LMVar
s can be used to build synchronization primitives and
communication channels (LMVar
s themselves are single-place
channels). We refer to Control.Concurrent.MVar for the full
documentation on MVars.
- type LMVar l a = LObj l (MVar a)
- newEmptyLMVar :: Label l => l -> LIO l (LMVar l a)
- newEmptyLMVarP :: PrivDesc l p => Priv p -> l -> LIO l (LMVar l a)
- newLMVar :: Label l => l -> a -> LIO l (LMVar l a)
- newLMVarP :: PrivDesc l p => Priv p -> l -> a -> LIO l (LMVar l a)
- takeLMVar :: Label l => LMVar l a -> LIO l a
- takeLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> LIO l a
- tryTakeLMVar :: Label l => LMVar l a -> LIO l (Maybe a)
- tryTakeLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> LIO l (Maybe a)
- putLMVar :: Label l => LMVar l a -> a -> LIO l ()
- putLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> a -> LIO l ()
- tryPutLMVar :: Label l => LMVar l a -> a -> LIO l Bool
- tryPutLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> a -> LIO l Bool
- readLMVar :: Label l => LMVar l a -> LIO l a
- readLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> LIO l a
- swapLMVar :: Label l => LMVar l a -> a -> LIO l a
- swapLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> a -> LIO l a
- isEmptyLMVar :: Label l => LMVar l a -> LIO l Bool
- isEmptyLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> LIO l Bool
Documentation
type LMVar l a = LObj l (MVar a) Source #
An LMVar
is a labeled synchronization variable (an MVar
) that
can be used by concurrent threads to communicate.
Creating labeled MVar
s
Create a new labeled MVar, in an empty state. Note that the supplied
label must be above the current label and below the current clearance.
An exception will be thrown by the underlying guardAlloc
if this is
not the case.
newEmptyLMVarP :: PrivDesc l p => Priv p -> l -> LIO l (LMVar l a) Source #
Same as newEmptyLMVar
except it takes a set of privileges which
are accounted for in comparing the label of the MVar to the current
label and clearance.
Create a new labeled MVar, in an filled state with the supplied value. Note that the supplied label must be above the current label and below the current clearance.
newLMVarP :: PrivDesc l p => Priv p -> l -> a -> LIO l (LMVar l a) Source #
Same as newLMVar
except it takes a set of privileges which are
accounted for in comparing the label of the MVar to the current label.
Take LMVar
takeLMVar :: Label l => LMVar l a -> LIO l a Source #
Return contents of the LMVar
. Note that a take consists of a read
and a write, since it observes whether or not the LMVar
is full, and
thus the current label must be the same as that of the LMVar
(of
course, this is not the case when using privileges). Hence, if the
label of the LMVar
is below the current clearance, we raise the
current label to the join of the current label and the label of the
MVar and read the contents of the MVar
. The underlying guard
guardWrite
will throw an exception if any of the IFC checks fail.
Finally, like MVars
if the LMVar
is empty, takeLMVar
blocks.
takeLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> LIO l a Source #
Same as takeLMVar
except takeLMVarP
takes a privilege object
which is used when the current label is raised.
tryTakeLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> LIO l (Maybe a) Source #
Same as tryTakeLMVar
, but uses priviliges when raising current
label.
Put LMVar
Puts a value into an LMVar
. Note that a put consists of a read and
a write, since it observes whether or not the LMVar
is empty, and so
the current label must be the same as that of the LMVar
(of course,
this is not the case when using privileges). As in the takeLMVar
case, if the label of the LMVar
is below the current clearance, we
raise the current label to the join of the current label and the label
of the MVar and put the value into the MVar
. Moreover if these IFC
restrictions fail, the underlying guardWrite
throws an exception.
If the LMVar
is full, putLMVar
blocks.
putLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> a -> LIO l () Source #
Same as putLMVar
except putLMVarP
takes a privilege object
which is used when the current label is raised.
Read LMVar
tryPutLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> a -> LIO l Bool Source #
Same as tryPutLMVar
, but uses privileges when raising current label.
readLMVar :: Label l => LMVar l a -> LIO l a Source #
Combination of takeLMVar
and putLMVar
. Read the value, and
just put it back. This operation is not atomic, and can can result
in unexpected outcomes if another thread is simultaneously calling
a function such as putLMVar
, tryTakeLMVarP
, or isEmptyLMVar
for this LMVar
.
readLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> LIO l a Source #
Same as readLMVar
except readLMVarP
takes a privilege object
which is used when the current label is raised.
Swap LMVar
Takes a value from an LMVar
, puts a new value into the LMvar
,
and returns the taken value. Like the other LMVar
operations it is
required that the label of the LMVar
be above the current label and
below the current clearance. Moreover, the current label is raised to
accommodate for the observation. The underlying guardWrite
throws an
exception if this cannot be accomplished. This operation is atomic iff
there is no other thread calling putLMVar
for this LMVar
.
swapLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> a -> LIO l a Source #
Same as swapLMVar
except swapLMVarP
takes a privilege object
which is used when the current label is raised.
Check state of LMVar
isEmptyLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> LIO l Bool Source #
Same as isEmptyLMVar
, but uses privileges when raising current label.