stm-io-hooks-1.1.2: src/Control/Concurrent/AdvSTM/TVar.hs
-----------------------------------------------------------------------------
-- |
-- Module : Control.Concurrent.AdvSTM.TVar
-- Copyright : (c) Peter Robinson 2009
-- License : BSD-style (see the file LICENSE)
--
-- Maintainer : Peter Robinson <robinson@ecs.tuwien.ac.at>
-- Stability : experimental
-- Portability : non-portable (requires STM)
--
--
--
-----------------------------------------------------------------------------
module Control.Concurrent.AdvSTM.TVar( -- * TVars
TVar
, newTVar
, newTVarIO
, readTVar
, writeTVar
, readTVarAsync
, writeTVarAsync
)
where
import Control.Monad.AdvSTM.Class
(readTVar,writeTVar,newTVar,TVar(TVar),valueTVar,readTVarAsync,writeTVarAsync)
import qualified Control.Concurrent.STM.TVar as OldTVar
import qualified Control.Concurrent.STM.TMVar as OldTMVar
import Control.Monad(liftM,ap)
{-
import qualified Control.Concurrent.STM as STM
import qualified Control.Concurrent.STM.TChan as OldTChan
import Control.Exception(throw,Deadlock(Deadlock))
import Control.Concurrent.AdvSTM(liftAdv,orElse,retry,readTVar,writeTVar,newTVar)
import Control.Monad.AdvSTM.Def(AdvSTM(AdvSTM),transThreadId,listeners,TVarValue(TVarValue))
import Control.Concurrent(ThreadId)
import Control.Monad.Reader(asks)
import Data.Maybe(isJust,Maybe,fromJust)
import qualified Data.Set as S
-}
--------------------------------------------------------------------------------
-- | See 'OldTVar.newTVarIO'
--
newTVarIO :: a -> IO (TVar a)
newTVarIO a = TVar `liftM` OldTVar.newTVarIO a
`ap` OldTMVar.newTMVarIO ()
`ap` OldTVar.newTVarIO Nothing
--------------------------------------------------------------------------------
{-
-- | See 'OldTVar.newTVar'
newTVar :: a -> AdvSTM (TVar a)
newTVar a = TVar `liftM` (liftAdv $ OldTVar.newTVar a)
`ap` (liftAdv $ OldTMVar.newTMVar ())
`ap` (liftAdv $ OldTVar.newTVar Nothing)
-}
{-
--------------------------------------------------------------------------------
-- | Writes a value to a TVar. Blocks until the onCommit IO-action(s) are
-- complete. See 'onCommit' for details.
writeTVar :: TVar a -> a -> AdvSTM ()
writeTVar tvar a = do
commitLock <- liftAdv $ OldTMVar.tryTakeTMVar (onCommitLock tvar)
-- Get ThreadID of current transaction:
curTid <- AdvSTM $ asks transThreadId
storedTid <- liftAdv $ OldTVar.readTVar (currentTid tvar)
case commitLock of
Nothing -> do
if isJust storedTid && fromJust storedTid == curTid
then throw Deadlock -- No transaction during onCommit-phase!
else retry
Just _ -> do
unless (isJust storedTid && (fromJust storedTid == curTid)) $ do
-- First write access, update the ThreadId:
liftAdv $ OldTVar.writeTVar (currentTid tvar) $ Just curTid
-- Add this TVar to the onCommit-listener list:
lsTVar <- AdvSTM $ asks listeners
ls <- liftAdv $ OldTVar.readTVar lsTVar
-- Remember the old value for rollback:
oldval <- liftAdv $ OldTVar.readTVar (valueTVar tvar)
liftAdv $ OldTVar.writeTVar lsTVar $
(onCommitLock tvar,TVarValue (valueTVar tvar,oldval)) : ls
liftAdv $ OldTVar.writeTVar (valueTVar tvar) a
liftAdv $ OldTMVar.putTMVar (onCommitLock tvar) ()
--------------------------------------------------------------------------------
-- | Reads a value from a TVar. Blocks until the IO onCommit action(s) of
-- the corresponding transaction are complete.
-- See 'onCommit' for a more detailed description of this behaviour.
readTVar :: TVar a -> AdvSTM a
readTVar tvar = do
commitLock <- liftAdv $ OldTMVar.tryTakeTMVar (onCommitLock tvar)
case commitLock of
Nothing -> do
storedTid <- liftAdv $ OldTVar.readTVar (currentTid tvar)
curTid <- AdvSTM $ asks transThreadId
if isJust storedTid && fromJust storedTid == curTid
then throw Deadlock
else retry
Just _ -> do
result <- liftAdv $ OldTVar.readTVar $ valueTVar tvar
liftAdv $ OldTMVar.putTMVar (onCommitLock tvar) ()
return result
--------------------------------------------------------------------------------
-}