{-# LANGUAGE CPP
, DeriveDataTypeable
, NoImplicitPrelude
, TupleSections
#-}
#if __GLASGOW_HASKELL__ >= 704
{-# LANGUAGE Safe #-}
#endif
module Control.Concurrent.ReadWriteVar
( RWVar
, new
, with
, tryWith
, modify_
, modify
, tryModify_
, tryModify
) where
import Control.Applicative ( liftA2 )
import Control.Monad ( (>>=) )
import Data.Bool ( Bool(..) )
import Data.Eq ( Eq, (==) )
import Data.Function ( ($), (.), on )
import Data.Functor ( fmap )
import Data.Maybe ( Maybe(..), isJust )
import Data.IORef ( IORef, newIORef, readIORef )
import Data.Typeable ( Typeable )
import System.IO ( IO )
#ifdef __HADDOCK_VERSION__
import Data.Function ( const )
import Prelude ( undefined )
#endif
import Control.Concurrent.ReadWriteLock ( RWLock )
import qualified Control.Concurrent.ReadWriteLock as RWLock
import Utils ( modifyIORefM, modifyIORefM_ )
data RWVar a = RWVar RWLock (IORef a) deriving Typeable
instance Eq (RWVar a) where
== :: RWVar a -> RWVar a -> Bool
(==) = RWLock -> RWLock -> Bool
forall a. Eq a => a -> a -> Bool
(==) (RWLock -> RWLock -> Bool)
-> (RWVar a -> RWLock) -> RWVar a -> RWVar a -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` RWVar a -> RWLock
forall {a}. RWVar a -> RWLock
rwlock
where
rwlock :: RWVar a -> RWLock
rwlock (RWVar RWLock
rwl IORef a
_) = RWLock
rwl
new :: a -> IO (RWVar a)
new :: forall a. a -> IO (RWVar a)
new = (RWLock -> IORef a -> RWVar a)
-> IO RWLock -> IO (IORef a) -> IO (RWVar a)
forall a b c. (a -> b -> c) -> IO a -> IO b -> IO c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 RWLock -> IORef a -> RWVar a
forall a. RWLock -> IORef a -> RWVar a
RWVar IO RWLock
RWLock.new (IO (IORef a) -> IO (RWVar a))
-> (a -> IO (IORef a)) -> a -> IO (RWVar a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IO (IORef a)
forall a. a -> IO (IORef a)
newIORef
with :: RWVar a -> (a -> IO b) -> IO b
with :: forall a b. RWVar a -> (a -> IO b) -> IO b
with (RWVar RWLock
l IORef a
r) a -> IO b
f = RWLock -> IO b -> IO b
forall a. RWLock -> IO a -> IO a
RWLock.withRead RWLock
l (IO b -> IO b) -> IO b -> IO b
forall a b. (a -> b) -> a -> b
$ IORef a -> IO a
forall a. IORef a -> IO a
readIORef IORef a
r IO a -> (a -> IO b) -> IO b
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> IO b
f
tryWith :: RWVar a -> (a -> IO b) -> IO (Maybe b)
tryWith :: forall a b. RWVar a -> (a -> IO b) -> IO (Maybe b)
tryWith (RWVar RWLock
l IORef a
r) a -> IO b
f = RWLock -> IO b -> IO (Maybe b)
forall a. RWLock -> IO a -> IO (Maybe a)
RWLock.tryWithRead RWLock
l (IO b -> IO (Maybe b)) -> IO b -> IO (Maybe b)
forall a b. (a -> b) -> a -> b
$ IORef a -> IO a
forall a. IORef a -> IO a
readIORef IORef a
r IO a -> (a -> IO b) -> IO b
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> IO b
f
modify_ :: RWVar a -> (a -> IO a) -> IO ()
modify_ :: forall a. RWVar a -> (a -> IO a) -> IO ()
modify_ (RWVar RWLock
l IORef a
r) = RWLock -> IO () -> IO ()
forall a. RWLock -> IO a -> IO a
RWLock.withWrite RWLock
l (IO () -> IO ()) -> ((a -> IO a) -> IO ()) -> (a -> IO a) -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IORef a -> (a -> IO a) -> IO ()
forall a. IORef a -> (a -> IO a) -> IO ()
modifyIORefM_ IORef a
r
modify :: RWVar a -> (a -> IO (a, b)) -> IO b
modify :: forall a b. RWVar a -> (a -> IO (a, b)) -> IO b
modify (RWVar RWLock
l IORef a
r) = RWLock -> IO b -> IO b
forall a. RWLock -> IO a -> IO a
RWLock.withWrite RWLock
l (IO b -> IO b)
-> ((a -> IO (a, b)) -> IO b) -> (a -> IO (a, b)) -> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IORef a -> (a -> IO (a, b)) -> IO b
forall a b. IORef a -> (a -> IO (a, b)) -> IO b
modifyIORefM IORef a
r
tryModify_ :: RWVar a -> (a -> IO a) -> IO Bool
tryModify_ :: forall a. RWVar a -> (a -> IO a) -> IO Bool
tryModify_ (RWVar RWLock
l IORef a
r) = (Maybe () -> Bool) -> IO (Maybe ()) -> IO Bool
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe () -> Bool
forall a. Maybe a -> Bool
isJust (IO (Maybe ()) -> IO Bool)
-> ((a -> IO a) -> IO (Maybe ())) -> (a -> IO a) -> IO Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RWLock -> IO () -> IO (Maybe ())
forall a. RWLock -> IO a -> IO (Maybe a)
RWLock.tryWithWrite RWLock
l (IO () -> IO (Maybe ()))
-> ((a -> IO a) -> IO ()) -> (a -> IO a) -> IO (Maybe ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IORef a -> (a -> IO a) -> IO ()
forall a. IORef a -> (a -> IO a) -> IO ()
modifyIORefM_ IORef a
r
tryModify :: RWVar a -> (a -> IO (a, b)) -> IO (Maybe b)
tryModify :: forall a b. RWVar a -> (a -> IO (a, b)) -> IO (Maybe b)
tryModify (RWVar RWLock
l IORef a
r) = RWLock -> IO b -> IO (Maybe b)
forall a. RWLock -> IO a -> IO (Maybe a)
RWLock.tryWithWrite RWLock
l (IO b -> IO (Maybe b))
-> ((a -> IO (a, b)) -> IO b) -> (a -> IO (a, b)) -> IO (Maybe b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IORef a -> (a -> IO (a, b)) -> IO b
forall a b. IORef a -> (a -> IO (a, b)) -> IO b
modifyIORefM IORef a
r