packages feed

atomic-modify 0.1.0.0 → 0.1.0.1

raw patch · 2 files changed

+78/−55 lines, 2 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

Files

atomic-modify.cabal view
@@ -1,14 +1,16 @@--- This file has been generated from package.yaml by hpack version 0.17.0.+-- This file has been generated from package.yaml by hpack version 0.20.0. -- -- see: https://github.com/sol/hpack+--+-- hash: b47558f51afd9007c96683e4f3ac5b24a8d05dcb4a8ab911849c4a7f9fbdbd57  name:           atomic-modify-version:        0.1.0.0+version:        0.1.0.1 synopsis:       A typeclass for mutable references that have an atomic modify operation.  description:    A typeclass for mutable references that have an atomic modify operation. Generalizes atomic modify operations in IO and STM contexts for IORef, MVar, TVar, and TMVar. category:       Concurrency-homepage:       https://github.com/chris-martin/haskell-libraries+homepage:       https://github.com/chris-martin/atomic-modify author:         Chris Martin <ch.martin@gmail.com> maintainer:     Chris Martin <ch.martin@gmail.com> license:        Apache-2.0@@ -22,7 +24,7 @@   default-extensions: NoImplicitPrelude   ghc-options: -Wall   build-depends:-      base >= 4.9 && < 4.10+      base >=4.9 && <4.11     , stm   exposed-modules:       Control.Concurrent.AtomicModify
src/Control/Concurrent/AtomicModify.hs view
@@ -9,21 +9,30 @@  -} -{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE BangPatterns, MultiParamTypeClasses #-}  module Control.Concurrent.AtomicModify-    ( AtomicModify (..)-    , atomicModifyStrict_-    , atomicModifyLazy_-    ) where+  ( AtomicModify (..)+  , atomicModifyStrict_+  , atomicModifyLazy_+  ) where  import Control.Concurrent.MVar (MVar, modifyMVar) import Control.Concurrent.STM (STM, TMVar, TVar, atomically, putTMVar, readTVar,                                takeTMVar, writeTVar)+import Control.Monad ((>>=))+import Data.Function (($), (&))+import Data.Functor (($>)) import Data.IORef (IORef, atomicModifyIORef, atomicModifyIORef')-import Prelude (IO, pure, ($), ($!))+import Prelude (IO, pure, ($!)) ++--------------------------------------------------------------------------------+--  Class+--------------------------------------------------------------------------------+ {- |+ A typeclass for mutable references that have an atomic modify operation.  Type variables:@@ -34,29 +43,51 @@ As the name "atomic" implies, these functions are useful for using mutable references in a safe way to prevent race conditions in a multithreaded program.+ -} class AtomicModify ref m where -    -- | Atomically modify the contents of a @ref@ (type @a@) and produce a-    -- value (type @b@). This is strict; it forces the value stored in the @ref@-    -- as well as the value returned.-    atomicModifyStrict :: ref a -> (a -> (a, b)) -> m b+  {- | -    -- | Atomically modify the contents of a @ref@ (type @a@) and produce a-    -- value (type @b@). This is lazy, which means if the program calls-    -- 'atomicModifyLazy' many times, but seldomly uses the value, thunks will-    -- pile up in memory resulting in a space leak.-    atomicModifyLazy :: ref a -> (a -> (a, b)) -> m b+  Atomically modify the contents of a @ref@ (type @a@) and produce a value (type+  @b@). This is strict; it forces the value stored in the @ref@ as well as the+  value returned. --- | Atomically modify the contents of a @ref@. This is strict; it forces the--- value stored in the @ref@ as well as the value returned.+  -}+  atomicModifyStrict :: ref a -> (a -> (a, b)) -> m b++  {- |++  Atomically modify the contents of a @ref@ (type @a@) and produce a value (type+  @b@). This is lazy, which means if the program calls 'atomicModifyLazy' many+  times, but seldomly uses the value, thunks will pile up in memory resulting in+  a space leak.++  -}+  atomicModifyLazy :: ref a -> (a -> (a, b)) -> m b+++--------------------------------------------------------------------------------+--  Functions+--------------------------------------------------------------------------------++{- |++Atomically modify the contents of a @ref@. This is strict; it forces the value+stored in the @ref@ as well as the value returned.++-} atomicModifyStrict_ :: AtomicModify v m => v a -> (a -> a) -> m () atomicModifyStrict_ ref f = atomicModifyStrict ref (\a -> (f a, ())) --- | Atomically modify the contents of a @ref@ (type @a@) and produce a value--- (type @b@). This is lazy, which means if the program calls--- 'atomicModifyLazy_' many times, but seldomly uses the value, thunks will pile--- up in memory resulting in a space leak.+{- |++Atomically modify the contents of a @ref@ (type @a@) and produce a value (type+@b@). This is lazy, which means if the program calls 'atomicModifyLazy_' many+times, but seldomly uses the value, thunks will pile up in memory resulting in a+space leak.++-} atomicModifyLazy_ :: AtomicModify v m => v a -> (a -> a) -> m () atomicModifyLazy_ ref f = atomicModifyLazy ref (\a -> (f a, ())) @@ -65,46 +96,36 @@ --  Instances -------------------------------------------------------------------------------- -instance AtomicModify IORef IO where+instance AtomicModify IORef IO+  where     atomicModifyLazy   ref f = atomicModifyIORef  ref f     atomicModifyStrict ref f = atomicModifyIORef' ref f -instance AtomicModify MVar IO where+instance AtomicModify MVar IO+  where     atomicModifyLazy   ref f = modifyMVar ref (\x -> pure $  f x)     atomicModifyStrict ref f = modifyMVar ref (\x -> pure $! f x) -instance AtomicModify TVar STM where--    atomicModifyLazy ref f = do-        a <- readTVar ref-        let (a', b) = f a-        writeTVar ref a'-        pure b--    atomicModifyStrict ref f = do-        a <- readTVar ref-        let (a', b) = f a-        writeTVar ref $! a'-        pure $! b--instance AtomicModify TMVar STM where--    atomicModifyLazy ref f = do-        a <- takeTMVar ref-        let (a', b) = f a-        putTMVar ref a'-        pure b+instance AtomicModify TVar STM+  where+    atomicModifyLazy ref f =+      readTVar ref >>= \a -> f a & \( a',  b) -> writeTVar ref a' $> b+    atomicModifyStrict ref f =+      readTVar ref >>= \a -> f a & \(!a', !b) -> writeTVar ref a' $> b -    atomicModifyStrict ref f = do-        a <- takeTMVar ref-        let (a', b) = f a-        putTMVar ref $! a'-        pure $! b+instance AtomicModify TMVar STM+  where+    atomicModifyLazy ref f =+      takeTMVar ref >>= \a -> f a & \( a',  b) -> putTMVar ref a' $> b+    atomicModifyStrict ref f =+      takeTMVar ref >>= \a -> f a & \(!a', !b) -> putTMVar ref a' $> b -instance AtomicModify TVar IO where+instance AtomicModify TVar IO+  where     atomicModifyLazy   ref f = atomically (atomicModifyLazy   ref f)     atomicModifyStrict ref f = atomically (atomicModifyStrict ref f) -instance AtomicModify TMVar IO where+instance AtomicModify TMVar IO+  where     atomicModifyLazy   ref f = atomically (atomicModifyLazy   ref f)     atomicModifyStrict ref f = atomically (atomicModifyStrict ref f)