Safe Haskell | None |
---|
MSampleVar
is a safer version of the Control.Concurrent.SampleVar in
base. The same problem as QSem(N) is being fixed, that of handling waiters
that die before being woken normally. For Control.Concurrent.SampleVar in
base this error can lead to thinking a full SampleVar
is really empty and
cause writeSampleVar
to hang. The MSampleVar
in this module is immune
to this error, and has a simpler implementation.
- data MSampleVar a
- newEmptySV :: IO (MSampleVar a)
- newSV :: a -> IO (MSampleVar a)
- emptySV :: MSampleVar a -> IO ()
- readSV :: MSampleVar a -> IO a
- writeSV :: MSampleVar a -> a -> IO ()
- isEmptySV :: MSampleVar a -> IO Bool
Sample Variables
data MSampleVar a Source
Sample variables are slightly different from a normal MVar
:
- Reading an empty
MSampleVar
causes the reader to block. (same astakeMVar
on emptyMVar
) - Reading a filled
MSampleVar
empties it and returns value. (same astakeMVar
) - Try reading a filled
MSampleVar
returns a Maybe value. (same astryTakeMVar
) - Writing to an empty
MSampleVar
fills it with a value, and potentially, wakes up a blocked reader (same as forputMVar
on emptyMVar
). - Writing to a filled
MSampleVar
overwrites the current value. (different fromputMVar
on fullMVar
.)
The readers queue in FIFO order, with the lead reader joining the writers in a second FIFO queue to access the stored value. Thus writers can jump the queue of non-leading waiting readers to update the value, but the lead reader has to wait on all previous writes to finish before taking the value.
This design choice emphasises that each reader sees the most up-to-date value possible while still guaranteeing progress.
newEmptySV :: IO (MSampleVar a)Source
newEmptySV
allocates a new MSampleVar in an empty state. No futher
allocation is done when using the MSampleVar
.
newSV :: a -> IO (MSampleVar a)Source
newSV
allocates a new MSampleVar containing the passed value. The value
is not evalated or forced, but stored lazily. No futher allocation is done
when using the MSampleVar
.
emptySV :: MSampleVar a -> IO ()Source
If the MSampleVar
is full, forget the value and leave it empty.
Otherwise, do nothing. This avoids any the FIFO queue of blocked readSV
threads.
emptySV
can block and be interrupted, in which case it does nothing. If
emptySV
returns then it left the MSampleVar
in an empty state.
readSV :: MSampleVar a -> IO aSource
writeSV :: MSampleVar a -> a -> IO ()Source
Write a value into the MSampleVar
, overwriting any previous value that
was there.
writeSV
can block and be interrupted, in which case it does nothing.
isEmptySV :: MSampleVar a -> IO BoolSource
isEmptySV
can block and be interrupted, in which case it does nothing.
If isEmptySV
returns then it reports the momentary status the
MSampleVar
. Using this value without producing unwanted race conditions
is left up to the programmer.