Safe Haskell | Trustworthy |
---|
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 of 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. Different from LIORef
s, taking and putting
LMVars
calls the write guard guardWrite
to enforce sound
information flow control.
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
and clearance.
Take LMVar
takeLMVar :: Label l => LMVar l a -> LIO l aSource
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 aSource
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 BoolSource
Same as tryPutLMVar
, but uses privileges when raising current label.
readLMVar :: Label l => LMVar l a -> LIO l aSource
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 aSource
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 aSource
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 BoolSource
Same as isEmptyLMVar
, but uses privileges when raising current label.