tbox-0.1.0: Control/Concurrent/TBox/Internal/Class.hs
-----------------------------------------------------------------------------
-- |
-- Module : Control.Concurrent.TBox.Internal.Class
-- Copyright : Peter Robinson 2009
-- License : LGPL
--
-- Maintainer : Peter Robinson <thaldyron@gmail.com>
-- Stability : experimental
-- Portability : non-portable (requires STM)
--
-- The type class 'TBox'.
--
--
-----------------------------------------------------------------------------
module Control.Concurrent.TBox.Internal.Class
where
import Control.Concurrent.AdvSTM
import Prelude hiding(readIO)
--------------------------------------------------------------------------------
-- | An instance of 'TBox' is a (Adv)STM variable that might contain a value of
-- some type 'a'. In contrast to a plain 'TVar (Maybe a)', a
-- 'TBox' has IO hooks that are executed transparently on writes and reads,
-- which makes it particularly suitable for implementing a persistent and thread-safe storage.
-- The type variable 'k' can be used to provide additional storage information, e.g.,
-- a filepath.
--
-- /Important:/ Note that the read/write functions of this type class, i.e.,
-- 'readIO', 'readSTM', 'writeIO', 'writeSTM', 'clearIO', 'clearSTM' should
-- /only/ be used to derive new
-- instances and do not serve to modify the state of a 'TBox'.
-- The interface defined in module 'TBox.Operations' provides
-- operations on 'TBox's that guarantee consistency.
--
-- See the module 'Control.Concurrent.TFile' for a sample instance.
class TBox t k a where
-- | Takes a key and an initial value
new :: k -> a -> AdvSTM (t k a)
-- | Takes a key and an initial value. Has a default implementation.
newIO :: k -> a -> IO (t k a)
newIO k a = atomically (new k a)
-- | Takes a key and returns an empty 't'
newEmpty :: k -> AdvSTM (t k a)
-- | Takes a key and returns an empty 't'. Has a default implementation.
newEmptyIO :: k -> IO (t k a)
newEmptyIO = atomically . newEmpty
-- -- | Return the key
-- getKey :: t k a -> AdvSTM k
-- | Used in 'TBox.write'.
writeSTM :: t k a -> a -> AdvSTM ()
-- | Used in 'TBox.write' during the commit phase.
-- Is guaranteed to be executed exactly once /iff/ the transaction commits.
writeIO :: t k a -> a -> IO ()
-- | Used in 'TBox.read'
readSTM :: t k a -> AdvSTM (Maybe a)
-- | Used in 'TBox.read' when retrying the transaction, which happens when the
-- 'TBox' has been marked \"dirty\".
-- Note: Might be executed multiple times for the
-- same 'TBox' in a single transaction. See 'unsafeRetryWith'.
readIO :: t k a -> IO (Maybe a)
-- | Used in 'TBox.clear'
clearSTM :: t k a -> AdvSTM ()
-- | Used in 'TBox.clear' during the commit phase.
-- Is guaranteed to be executed exactly once /iff/ the transaction commits.
clearIO :: t k a -> IO ()
-- | If 'isDirty' yields 'True', the 'readIO' hook will be
-- run on the next read.
isDirty :: t k a -> AdvSTM Bool
-- | Change the \"dirty\" status of the 'TBox'.
setDirty :: t k a -> Bool -> AdvSTM ()
{-
-- TODO: what about modify?
modifySTM :: t k a -> (a -> a) -> AdvSTM ()
modifyIO :: t k a -> (a -> a) -> IO (Maybe a)
modifySTM t f = readSTM t >>= writeSTM t . f
modifyIO t f = readIO t >>= writeIO t
-}