{-# LANGUAGE CPP, MultiParamTypeClasses, FlexibleInstances #-} -- |This module exports no new symbols of its own. It defines -- basic class instances for creating, reading, and writing 'TVar's and -- (if available) 'TMVar's, and re-exports the types for which it defines -- instances as well as the 'atomically' function, which is indispensible -- when playing with this stuff in ghci. module Data.MRef.Instances.STM ( STM #ifdef useTMVar , TMVar #endif , TVar , atomically ) where import Data.MRef.Types import Data.StateRef (readReference, writeReference, newReference) import Data.StateRef.Instances.STM () import Control.Concurrent.STM -- MRef STM in IO monad instance NewMRef (MRef STM a) IO a where #ifdef useTMVar newMReference = fmap MRef . newTMVarIO newEmptyMReference = fmap MRef newEmptyTMVarIO #else newMReference = fmap MRef . newTVarIO . Just newEmptyMReference = fmap MRef (newTVarIO Nothing) #endif instance TakeMRef (MRef STM a) IO a where takeMReference (MRef ref) = atomically (takeMReference ref) instance PutMRef (MRef STM a) IO a where putMReference (MRef ref) = atomically . putMReference ref #ifdef useTMVar --TMVar in STM monad instance HasMRef STM where newMRef x = fmap MRef (newTMVar x) newEmptyMRef = fmap MRef newEmptyTMVar instance NewMRef (TMVar a) STM a where newMReference = newTMVar newEmptyMReference = newEmptyTMVar instance TakeMRef (TMVar a) STM a where takeMReference = takeTMVar instance PutMRef (TMVar a) STM a where putMReference = putTMVar -- TMVar in IO monad instance NewMRef (TMVar a) IO a where newMReference = newTMVarIO newEmptyMReference = newEmptyTMVarIO instance TakeMRef (TMVar a) IO a where takeMReference = atomically . takeMReference instance PutMRef (TMVar a) IO a where putMReference ref = atomically . putMReference ref #endif -- incidental instances, which may occasionally be handy in a pinch -- TVars containing "Maybe" values in STM monad. -- Also use as default if TMVar isn't available. #ifndef useTMVar instance HasMRef STM where newMRef x = fmap MRef (newTVar (Just x)) newEmptyMRef = fmap MRef (newTVar Nothing) #endif instance NewMRef (TVar (Maybe a)) STM a where newMReference = newReference . Just newEmptyMReference = newReference Nothing instance TakeMRef (TVar (Maybe a)) STM a where takeMReference ref = do x <- readReference ref case x of Nothing -> retry Just x -> do writeReference ref Nothing return x instance PutMRef (TVar (Maybe a)) STM a where putMReference ref val = do x <- readReference ref case x of Nothing -> writeReference ref (Just val) Just x -> retry -- TVars containing "Maybe" values in IO monad instance NewMRef (TVar (Maybe a)) IO a where newMReference = newReference . Just newEmptyMReference = newReference Nothing instance TakeMRef (TVar (Maybe a)) IO a where takeMReference = atomically . takeMReference instance PutMRef (TVar (Maybe a)) IO a where putMReference ref = atomically . putMReference ref