module Control.Monad.Trans.Order.Lazy.Internals (
OrderT (OrderT),
OrderRep (OrderRep),
emptyOrderRep,
Lock,
criticalSection
) where
import Control.Monad
import Control.Applicative
import Control.Monad.Trans.Class
import Control.Monad.IO.Class
import Control.Monad.Trans.State.Lazy
import Control.Monad.ST
import Control.Concurrent.MVar
import Control.Monad.Trans.Order.Raw
import System.IO.Unsafe
newtype OrderT o m a = OrderT (StateT (OrderRep o) m a) deriving (
Functor,
Applicative,
Alternative,
Monad,
MonadPlus,
MonadTrans,
MonadIO)
data OrderRep o = OrderRep (RawOrder o RealWorld)
(RawAlgorithm o RealWorld)
Lock
emptyOrderRep :: (forall s . RawAlgorithm o s) -> OrderRep o
emptyOrderRep rawAlg = unsafePerformIO $ do
rawOrder <- stToIO (newOrder rawAlg)
lock <- newLock
return (OrderRep rawOrder rawAlg lock)
type Lock = MVar ()
newLock :: IO Lock
newLock = newEmptyMVar
criticalSection :: Lock -> IO a -> IO a
criticalSection lock act = do
putMVar lock ()
val <- act
takeMVar lock
return val