-----------------------------------------------------------------------------
-- |
-- Module      :  Control.Monad.AdvSTM.Def
-- Copyright   :  (c) HaskellWiki 2006-2007, Peter Robinson 2008
-- License     :  BSD3
-- 
-- Maintainer  :  Peter Robinson <robinson@ecs.tuwien.ac.at>
-- Stability   :  experimental
-- Portability :  non-portable (requires STM)
--
--
-- This is an internal module.
-----------------------------------------------------------------------------
 
module Control.Monad.AdvSTM.Def(AdvSTM(..),Env(..),TVarValue(..))
where

import qualified Control.Concurrent.STM as S
import Control.Concurrent.STM.TVar(TVar) 
import Control.Concurrent.STM.TMVar(TMVar) 
import Control.Concurrent(MVar,ThreadId)
import Control.Monad(Monad,MonadPlus)
import Control.Monad.Reader(ReaderT,mapReaderT,runReaderT)

-- | Drop-in replacement for the STM monad
newtype AdvSTM a = AdvSTM (ReaderT Env S.STM a)
                deriving ( Functor
                         , Monad
                         , MonadPlus
                         )



-- | The environment used for the Reader Monad
data Env = Env { commitTVar    :: TVar [IO ()]        -- the commit action(s)
               , retryDoneMVar     :: MVar (Maybe ()) -- (IO () -> IO ()) -- the retry action(s)
               , transThreadId :: ThreadId            -- the current ThreadId
               , listeners     :: TVar [(TMVar (),TVarValue)] -- ,TVar (Maybe ThreadId),TChan (Maybe ThreadId))]
                                    -- Contains communication facilities for modified TVars: 
                                    -- [(tVar-Lock,Old-tVar-Value,Maybe (current ThreadId)
                                    --  ,death-notice channel)]
               , debugModeVar :: TVar Bool
--               , isInRetryMode :: TVar Bool
               }

data TVarValue = forall a. TVarValue ((TVar a),a)