lio-0.11.0.0: Labeled IO Information Flow Control Library

Safe HaskellTrustworthy

LIO.Concurrent.LMVar

Contents

Description

This module implements labeled MVars. The interface is analogous to Control.Concurrent.MVar, but the operations take place in the LIO monad. A labeled MVar, of type LMVar l a, is a mutable location that can be in of of two states; an LMVar 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 LIORefs (see LIO.LIORef), this label is fixed and does not change according to the content placed into the location. Different from LIORefs, taking and putting LMVars calls the write guard guardWrite to enforce sound information flow control.

LMVars can be used to build synchronization primitives and communication channels (LMVars themselves are single-place channels). We refer to Control.Concurrent.MVar for the full documentation on MVars.

Synopsis

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 MVars

newEmptyLMVarSource

Arguments

:: Label l 
=> l

Label of LMVar

-> LIO l (LMVar l a)

New mutable location

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.

newLMVarSource

Arguments

:: Label l 
=> l

Label of LMVar

-> a

Initial value of LMVar

-> LIO l (LMVar l a)

New mutable location

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.

tryTakeLMVar :: Label l => LMVar l a -> LIO l (Maybe a)Source

Non-blocking version of takeLMVar. It returns Nothing if the LMVar is empty, otherwise it returns Just value, emptying the LMVar.

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

putLMVarSource

Arguments

:: Label l 
=> LMVar l a

Source LMVar

-> a

New value

-> LIO l () 

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

tryPutLMVar :: Label l => LMVar l a -> a -> LIO l BoolSource

Non-blocking version of putLMVar. It returns True if the LMVar was empty and the put succeeded, otherwise it returns False.

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

swapLMVarSource

Arguments

:: Label l 
=> LMVar l a

Source LMVar

-> a

New value

-> LIO l a

Taken value

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

isEmptyLMVar :: Label l => LMVar l a -> LIO l BoolSource

Check the status of an LMVar, i.e., whether it is empty. The function succeeds if the label of the LMVar is below the current clearance -- the current label is raised to the join of the LMVar label and the current label.

isEmptyLMVarP :: PrivDesc l p => Priv p -> LMVar l a -> LIO l BoolSource

Same as isEmptyLMVar, but uses privileges when raising current label.