--------------------------------------------------------------------------{- |
Module : Control.Concurrent.STM.MonadIO
Copyright : (c) 2010 Galois, Inc.
License : BSD-style (see the file libraries/base/LICENSE)
Maintainer : John Launchbury, john@galois.com
Stability : experimental
Portability : concurrency, requires STM
Overloads the standard operations on TVars, and TMVars as defined
in Control.Concurrent.STM.
TVars and MVars are often thought of as variables to be
used in the STM monad. But in practice, they should be used
just as frequently (if not more so) in any IO-like monad, with STM
being used purely when a new atomic transaction is being defined.
Thus we reverse the naming convention, and use
the plain access names when in the IO-like monad, and use an explicit STM
suffix when using the variables tentatively within the STM monad itself.
TMVars are particularly valuable when used in an IO-like monad,
because operations like readTMVar and modifyTMvar
can guarantee the atomicity of the operation (unlike the corresponding
operations over MVars).
The standard operations on 'TVar' and 'TMVar' (such as
'writeTVar' or 'newEmptyTMVar') are overloaded over the
'MonadIO' class. A monad @m@ is declared an instance of
'MonadIO' by defining a function
> liftIO :: IO a -> m a
It also overloads the 'atomically' function, so that STM transactions
can be defined from within any MonadIO monad.
-}{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}moduleControl.Concurrent.STM.MonadIO(STM,atomically,always,alwaysSucceeds,retry,orElse,check,catchSTM,S.TVar,newTVar,readTVar,writeTVar,registerDelay,modifyTVar,modifyTVar_,newTVarSTM,readTVarSTM,writeTVarSTM,S.TMVar,newTMVar,newEmptyTMVar,takeTMVar,putTMVar,readTMVar,swapTMVar,tryTakeTMVar,tryPutTMVar,isEmptyTMVar,modifyTMVar,modifyTMVar_,newTMVarSTM,newEmptyTMVarSTM,takeTMVarSTM,putTMVarSTM,readTMVarSTM,swapTMVarSTM,tryTakeTMVarSTM,tryPutTMVarSTM,isEmptyTMVarSTM)whereimportControl.Monad.STMhiding(atomically)importqualifiedControl.Concurrent.STMasSimportControl.Concurrent.MonadIOimportGHC.Conc(readTVarIO)--------------------------------------------------------------------------- | The atomically function allows STM to be called directly from any-- monad which contains IO, i.e. is a member of MonadIO.atomically::MonadIOio=>STMa->ioaatomicallym=liftIO$S.atomicallym-------------------------------------------------------------------------typeTVar=S.TVarnewTVar::MonadIOio=>a->io(TVara)newTVarx=liftIO$S.newTVarIOxreadTVar::MonadIOio=>TVara->ioareadTVart=liftIO$readTVarIOtwriteTVar::MonadIOio=>TVara->a->io()writeTVartx=atomically$writeTVarSTMtxregisterDelay::MonadIOio=>Int->io(TVarBool)registerDelayn=liftIO$S.registerDelayn-- | 'modifyTVar' is an atomic update operation which provides both-- the former value and the newly computed value as a result.modifyTVar::MonadIOio=>TVara->(a->a)->io(a,a)modifyTVartf=atomically$dox<-readTVarSTMtlety=fxseqy$writeTVarSTMtyreturn(x,y)modifyTVar_::MonadIOio=>TVara->(a->a)->io()modifyTVar_tf=atomically$dox<-readTVarSTMtlety=fxseqy$writeTVarSTMty----------------------newTVarSTM::a->STM(TVara)newTVarSTMx=S.newTVarxreadTVarSTM::TVara->STMareadTVarSTMt=S.readTVartwriteTVarSTM::TVara->a->STM()writeTVarSTMtx=S.writeTVartx-------------------------------------------------------------------------typeTMVara=S.TMVaranewTMVar::MonadIOio=>a->io(TMVara)newTMVarx=liftIO$S.newTMVarIOxnewEmptyTMVar::MonadIOio=>io(TMVara)newEmptyTMVar=liftIO$S.newEmptyTMVarIOtakeTMVar::MonadIOio=>TMVara->ioatakeTMVart=atomically$takeTMVarSTMtputTMVar::MonadIOio=>TMVara->a->io()putTMVartx=atomically$putTMVarSTMtxreadTMVar::MonadIOio=>TMVara->ioareadTMVart=atomically$readTMVarSTMtswapTMVar::MonadIOio=>TMVara->a->ioaswapTMVartx=atomically$swapTMVarSTMtxtryTakeTMVar::MonadIOio=>TMVara->io(Maybea)tryTakeTMVart=atomically$tryTakeTMVarSTMttryPutTMVar::MonadIOio=>TMVara->a->ioBooltryPutTMVartx=atomically$tryPutTMVarSTMtxisEmptyTMVar::MonadIOio=>TMVara->ioBoolisEmptyTMVart=atomically$isEmptyTMVarSTMt-- modifyTMVar is an atomic update operation which provides both-- the former value and the newly computed value as a result.modifyTMVar::MonadIOio=>TMVara->(a->a)->io(a,a)modifyTMVartf=atomically$dox<-takeTMVarSTMtlety=fxseqy$putTMVarSTMtyreturn(x,y)modifyTMVar_::MonadIOio=>TMVara->(a->a)->io()modifyTMVar_tf=atomically$dox<-takeTMVarSTMtlety=fxseqy$putTMVarSTMty----------------------newTMVarSTM::a->STM(TMVara)newTMVarSTM=S.newTMVarnewEmptyTMVarSTM::STM(TMVara)newEmptyTMVarSTM=S.newEmptyTMVartakeTMVarSTM::TMVara->STMatakeTMVarSTM=S.takeTMVarputTMVarSTM::TMVara->a->STM()putTMVarSTM=S.putTMVarreadTMVarSTM::TMVara->STMareadTMVarSTM=S.readTMVarswapTMVarSTM::TMVara->a->STMaswapTMVarSTM=S.swapTMVartryTakeTMVarSTM::TMVara->STM(Maybea)tryTakeTMVarSTM=S.tryTakeTMVartryPutTMVarSTM::TMVara->a->STMBooltryPutTMVarSTM=S.tryPutTMVarisEmptyTMVarSTM::TMVara->STMBoolisEmptyTMVarSTM=S.isEmptyTMVar