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)