packages feed

AVar 0.0.2 → 0.0.3

raw patch · 2 files changed

+39/−22 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.AVar: JustMod :: (a -> a) -> Transaction a
+ Data.AVar: justModAVar :: AVar a -> (a -> a) -> IO ()
+ Data.AVar: putAVar :: AVar a -> a -> IO ()

Files

AVar.cabal view
@@ -1,5 +1,5 @@ Name:                   AVar-Version:                0.0.2+Version:                0.0.3 Category:               Concurrency Synopsis:               Mutable variables with Exception handling and concurrency support. Description:            AVars emulate mutable variables, by providing a queue based interface to interacting with the variable. Each variable runs a 'handler' function, which reads requests from a queue and processes them one by one. They can be used in concurrent systems safely, and should handle exceptions thrown by modifying functions gracefully.
Data/AVar.hs view
@@ -6,17 +6,29 @@  -- |AVars are a form of transactional variables. They internally use a tail -- recursive function to carry the 'state' of the variable, and allow for--- use in concurrent systems, where actions are quaranteed to happen. They--- are designed to cope with exceptions thrown by any modifying functions.+-- use in concurrent systems, where actions are guaranteed to happen. They+-- are designed to cope with exceptions thrown by any modifying functions;+-- any exception thrown during a transaction will either be passed back to+-- the caller or ignored, and the variable keeps on running.+--+-- They are handy for applications like keeping track of resources by+-- incrementing and decrementing the variable. They should not be used in+-- a way which you would read the variable, then modify it based on the+-- result recieved, but rather using the provided functions. If this was+-- not done, the variable's value is very likely to have changed in the+-- mean time.+ module Data.AVar (     -- * Types     AVar,     Transaction(..),     -- * functions on AVars+    putAVar,     newAVar,     putMVar,     modAVar,     modAVar',+    justModAVar,     getAVar,     condModAVar,     swapAVar) where@@ -24,7 +36,6 @@ import Control.Concurrent.MVar import Control.Concurrent.Chan import qualified Control.Exception as E-import System.Environment  -- * Types @@ -37,6 +48,8 @@     -- ^reads the variable     | Mod (a -> a) (MVar (Maybe E.SomeException))     -- ^modifies the variable+    | JustMod (a -> a)+    -- ^ Just modifies the variable (unless an exception occurs)     | forall b. Mod' (a -> (a,b)) (MVar (Either E.SomeException b))     -- ^ modifies the variable, returning the b result to the caller     | Atom (a -> Bool) (a -> a) (a -> a) (MVar (Either E.SomeException Bool))@@ -81,6 +94,12 @@         case p of           Nothing -> handler chan x'           _       -> handler chan x+    JustMod f     -> do+        let x' = f x+        res <- E.try (E.evaluate x')+        case res of+            Right _                    -> handler chan x'+            Left  (_::E.SomeException) -> handler chan x            Mod' f mvar    -> do           let y@(a,b) = f x@@ -118,6 +137,15 @@         --           putMVar res False         --           handler chan (n x) ++-- |'getAVar' reads the current value inside the AVar.+getAVar :: AVar a -> IO a+getAVar (AVar chan)   = do+    res <- newEmptyMVar+    writeChan chan (Get res)+    takeMVar res++ -- |'putAVar' replaces the currect value in the variable with the given x putAVar :: AVar a -> a -> IO () putAVar (AVar chan) x = writeChan chan (Put x)@@ -138,12 +166,13 @@     writeChan chan (Mod' f res)     takeMVar res --- |'getAVar' reads the current value inside the AVar.-getAVar :: AVar a -> IO a-getAVar (AVar chan)   = do-    res <- newEmptyMVar-    writeChan chan (Get res)-    takeMVar res+-- |'justModAVar' will attempt to run the given function on the variable.+-- It does not report back on its sucess or failure, and if the function+-- produces an exception, the variable is left unchanged. It should be+-- used when you just want to modify the variable, and keep running,+-- without waiting for the action to complete.+justModAVar :: AVar a -> (a -> a) -> IO ()+justModAVar (AVar chan) f = writeChan chan (JustMod f)  -- |'condModAVar' applies the first finction to the current value in the -- AVar, and if true will modify the value using the second function if@@ -164,18 +193,6 @@     res <- newEmptyMVar     writeChan chan (Mod' (\old -> (new, old)) res)     takeMVar res--main = do-    n <- getArgs >>= \xs -> if null xs then return 1000000 else (readIO.head) xs-    var <- newAVar (0 :: Int)-    m <- newEmptyMVar-    forkIO $ test n var m-    takeMVar m-    where test 0 _ m   = putMVar m ()-          test n var m = do-              res <- getAVar var-              putAVar var (res + 1)-              test (n-1) var m