packages feed

concurrency 1.1.2.0 → 1.1.2.1

raw patch · 20 files changed

+328/−208 lines, 20 filessetup-changedPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Control.Monad.Conc.Class: class (Applicative m, Monad m, MonadCatch m, MonadThrow m, MonadMask m, MonadSTM (STM m), Ord (ThreadId m), Show (ThreadId m)) => MonadConc m where type STM m :: * -> * type MVar m :: * -> * type CRef m :: * -> * type Ticket m :: * -> * type ThreadId m :: * fork ma = forkWithUnmask (\ _ -> ma) forkWithUnmask = forkWithUnmaskN "" forkWithUnmaskN _ = forkWithUnmask forkOn c ma = forkOnWithUnmask c (\ _ -> ma) forkOnWithUnmask = forkOnWithUnmaskN "" forkOnWithUnmaskN _ = forkOnWithUnmask threadDelay _ = yield newEmptyMVar = newEmptyMVarN "" newEmptyMVarN _ = newEmptyMVar newCRef = newCRefN "" newCRefN _ = newCRef readCRef cref = readForCAS cref >>= peekTicket atomicWriteCRef r a = atomicModifyCRef r $ const (a, ()) modifyCRefCAS_ cref f = modifyCRefCAS cref (\ a -> (f a, ())) readTVarConc = atomically . readTVar where {
+ Control.Monad.Conc.Class: class (Applicative m, Monad m, MonadCatch m, MonadThrow m, MonadMask m, MonadSTM (STM m), Ord (ThreadId m), Show (ThreadId m)) => MonadConc m where type STM m :: * -> * type MVar m :: * -> * type CRef m :: * -> * type Ticket m :: * -> * type ThreadId m :: * fork ma = forkWithUnmask (const ma) forkWithUnmask = forkWithUnmaskN "" forkWithUnmaskN _ = forkWithUnmask forkOn c ma = forkOnWithUnmask c (const ma) forkOnWithUnmask = forkOnWithUnmaskN "" forkOnWithUnmaskN _ = forkOnWithUnmask threadDelay _ = yield newEmptyMVar = newEmptyMVarN "" newEmptyMVarN _ = newEmptyMVar newCRef = newCRefN "" newCRefN _ = newCRef readCRef cref = readForCAS cref >>= peekTicket atomicWriteCRef r a = atomicModifyCRef r $ const (a, ()) modifyCRefCAS_ cref f = modifyCRefCAS cref (\ a -> (f a, ())) readTVarConc = atomically . readTVar where {

Files

+ CHANGELOG.markdown view
@@ -0,0 +1,110 @@+Release Notes+=============++All notable changes to this project will be documented in this file.++This project is versioned according to the [Package Versioning Policy](https://pvp.haskell.org), the+*de facto* standard Haskell versioning scheme.+++1.1.2.1 [2017-06-07] (tag: [concurrency-1.1.2.1][])+-------++https://hackage.haskell.org/package/concurrency-1.1.2.1++### Changed++- The `isEmptyMVar` function is now implemented using `tryReadMVar` instead of a combination of+  `tryTakeMVar` and `putMVar`. It no longer modifies the contents of the `MVar` and can no longer+  block.++### Miscellaneous++- There is now a changelog.++[concurrency-1.1.2.1]: https://github.com/barrucadu/dejafu/releases/tag/concurrency-1.1.2.1+++---------------------------------------------------------------------------------------------------+++1.1.2.0 [2017-04-05] (tag: [concurrency-1.1.2.0][])+-------++https://hackage.haskell.org/package/concurrency-1.1.2.0++### Control.Concurrent.Classy.Async++- New functions:+    - `uninterruptibleCancel` function, which is `cancel` inside an+      uninterruptible mask.+    - `replicateConcurrently` function, which performs an action many+      times in separate threads.+    - `concurrently_`, `mapConcurrently_`, `forConcurrently_`, and+      `replicateConcurrently_` functions, which discard the result of+      the non-_ version.+- New instances:+    - `Semigroup` instance for `Concurrently` when built with base 4.9.+    - `Monoid` instance for `Concurrently`.++### Control.Monad.Conc.Class++- The `mask_` and `uninterruptibleMask_` functions from Control.Monad.Catch are now re-exported.++### Changed++- The `cancel` and the `withAsync` functions now block until the `Async` action terminates, to match+  changes in the main async package.++### Miscellaneous++- Every definition, class, and instance now has a Haddock "@since" annotation.++[concurrency-1.1.2.0]: https://github.com/barrucadu/dejafu/releases/tag/concurrency-1.1.2.0+++---------------------------------------------------------------------------------------------------+++1.1.1.0 [2017-03-04] (git tag: [concurrency-1.1.1.0][])+-------++https://hackage.haskell.org/package/concurrency-1.1.1.0++### Miscellaneous++- The async-dejafu package has been pulled into this package as the Control.Concurrent.Classy.Async+  module. async-dejafu is now __deprecated__.++[concurrency-1.1.1.0]: https://github.com/barrucadu/dejafu/releases/tag/concurrency-1.1.1.0+++---------------------------------------------------------------------------------------------------+++1.1.0.0 [2017-02-21] (git tag: [concurrency-1.1.0.0][])+-------++https://hackage.haskell.org/package/concurrency-1.1.0.0++### Control.Monad.Conc.Class++- The `MonadConc` class now defines `tryReadMVar`, a non-blocking version of `readMVar` akin to+  `tryTakeMVar`.+- The `MonadConc` class no longer defines `_concMessage`, there is no alternative provided, it is+  just gone.++[concurrency-1.1.0.0]: https://github.com/barrucadu/dejafu/releases/tag/concurrency-1.1.0.0+++---------------------------------------------------------------------------------------------------+++1.0.0.0 [2016-09-10] (git tag: [concurrency-1.0.0.0][])+-------++https://hackage.haskell.org/package/concurrency-1.0.0.0++Initial release. Go read the API docs.++[concurrency-1.0.0.0]: https://github.com/barrucadu/dejafu/releases/tag/concurrency-1.0.0.0
Control/Concurrent/Classy.hs view
@@ -29,12 +29,10 @@   , module Control.Concurrent.Classy.QSemN   ) where -import Control.Monad.Conc.Class-import Control.Concurrent.Classy.Chan-import Control.Concurrent.Classy.CRef-import Control.Concurrent.Classy.MVar-import Control.Concurrent.Classy.STM-import Control.Concurrent.Classy.QSem-import Control.Concurrent.Classy.QSemN--{-# ANN module ("HLint: ignore Use import/export shortcut" :: String) #-}+import           Control.Concurrent.Classy.Chan+import           Control.Concurrent.Classy.CRef+import           Control.Concurrent.Classy.MVar+import           Control.Concurrent.Classy.QSem+import           Control.Concurrent.Classy.QSemN+import           Control.Concurrent.Classy.STM+import           Control.Monad.Conc.Class
Control/Concurrent/Classy/Async.hs view
@@ -77,18 +77,21 @@   , Concurrently(..)   ) where -import Control.Applicative-import Control.Concurrent.Classy.STM.TMVar (newEmptyTMVar, putTMVar, readTMVar)-import Control.Exception (AsyncException(ThreadKilled), BlockedIndefinitelyOnSTM(..), Exception, SomeException)-import Control.Monad-import Control.Monad.Catch (finally, try, onException)-import Control.Monad.Conc.Class-import Control.Monad.STM.Class-import Data.Foldable (foldMap)-import Data.Traversable+import           Control.Applicative+import           Control.Concurrent.Classy.STM.TMVar (newEmptyTMVar, putTMVar,+                                                      readTMVar)+import           Control.Exception                   (AsyncException(ThreadKilled),+                                                      BlockedIndefinitelyOnSTM(..),+                                                      Exception, SomeException)+import           Control.Monad+import           Control.Monad.Catch                 (finally, onException, try)+import           Control.Monad.Conc.Class+import           Control.Monad.STM.Class+import           Data.Foldable                       (foldMap)+import           Data.Traversable  #if MIN_VERSION_base(4,9,0)-import Data.Semigroup (Semigroup(..))+import           Data.Semigroup                      (Semigroup(..)) #endif  -----------------------------------------------------------------------------------------@@ -142,7 +145,7 @@  -- | @since 1.1.1.0 instance MonadConc m => Applicative (Concurrently m) where-  pure = Concurrently . return+  pure = Concurrently . pure    Concurrently fs <*> Concurrently as =     Concurrently $ (\(f, a) -> f a) <$> concurrently fs as@@ -199,8 +202,7 @@ asyncUsing doFork action = do   var <- atomically newEmptyTMVar   tid <- mask $ \restore -> doFork $ try (restore action) >>= atomically . putTMVar var--  return $ Async tid (readTMVar var)+  pure (Async tid (readTMVar var))  -- | Fork a thread with the given forking function and give it an -- action to unmask exceptions@@ -208,8 +210,7 @@ asyncUnmaskUsing doFork action = do   var <- atomically newEmptyTMVar   tid <- doFork $ \restore -> try (action restore) >>= atomically . putTMVar var--  return $ Async tid (readTMVar var)+  pure (Async tid (readTMVar var))  -- | Spawn an asynchronous action in a separate thread, and pass its -- @Async@ handle to the supplied function. When the function returns@@ -245,36 +246,30 @@ withAsyncOnWithUnmask :: MonadConc m => Int -> ((forall x. m x -> m x) -> m a) -> (Async m a -> m b) -> m b withAsyncOnWithUnmask i = withAsyncUnmaskUsing (forkOnWithUnmask i) --- | Fork a thread with the given forking function and kill it when--- the inner action completes.------ The 'bracket' version appears to hang, even with just IO stuff and--- using the normal async package. Curious.+-- | Helper for 'withAsync' and 'withAsyncOn': fork a thread with the+-- given forking function and kill it when the inner action completes. withAsyncUsing :: MonadConc m => (m () -> m (ThreadId m)) -> m a -> (Async m a -> m b) -> m b withAsyncUsing doFork action inner = do   var <- atomically newEmptyTMVar   tid <- mask $ \restore -> doFork $ try (restore action) >>= atomically . putTMVar var--  let a = Async tid (readTMVar var)--  res <- inner a `catchAll` (\e -> uninterruptibleCancel a >> throw e)-  cancel a--  return res+  withAsyncDo (Async tid (readTMVar var)) inner --- | Fork a thread with the given forking function, give it an action--- to unmask exceptions, and kill it when the inner action completed.+-- | Helper for 'withAsyncWithUnmask' and 'withAsyncOnWithUnmask':+-- fork a thread with the given forking function, give it an action to+-- unmask exceptions, and kill it when the inner action completed. withAsyncUnmaskUsing :: MonadConc m => (((forall x. m x -> m x) -> m ()) -> m (ThreadId m)) -> ((forall x. m x -> m x) -> m a) -> (Async m a -> m b) -> m b withAsyncUnmaskUsing doFork action inner = do   var <- atomically newEmptyTMVar   tid <- doFork $ \restore -> try (action restore) >>= atomically . putTMVar var--  let a = Async tid (readTMVar var)+  withAsyncDo (Async tid (readTMVar var)) inner +-- | Helper for 'withAsyncUsing' and 'withAsyncUnmaskUsing': run the+-- inner action and kill the async thread when done.+withAsyncDo :: MonadConc m => Async m a -> (Async m a -> m b) -> m b+withAsyncDo a inner = do   res <- inner a `catchAll` (\e -> uninterruptibleCancel a >> throw e)   cancel a--  return res+  pure res  catchAll :: MonadConc m => m a -> (SomeException -> m a) -> m a catchAll = catch@@ -298,7 +293,7 @@ waitSTM :: MonadConc m => Async m a -> STM m a waitSTM a = do  r <- waitCatchSTM a- either throwSTM return r+ either throwSTM pure r  -- | Check whether an 'Async' has completed yet. If it has not -- completed yet, then the result is @Nothing@, otherwise the result@@ -315,7 +310,7 @@ -- -- @since 1.1.1.0 pollSTM :: MonadConc m => Async m a -> STM m (Maybe (Either SomeException a))-pollSTM (Async _ w) = (Just <$> w) `orElse` return Nothing+pollSTM (Async _ w) = (Just <$> w) `orElse` pure Nothing  -- | Wait for an asynchronous action to complete, and return either -- @Left e@ if the action raised an exception @e@, or @Right a@ if it@@ -391,7 +386,7 @@ -- -- @since 1.1.1.0 waitAnySTM :: MonadConc m => [Async m a] -> STM m (Async m a, a)-waitAnySTM = foldr (orElse . (\a -> do r <- waitSTM a; return (a, r))) retry+waitAnySTM = foldr (orElse . (\a -> do r <- waitSTM a; pure (a, r))) retry  -- | Wait for any of the supplied asynchronous operations to complete. -- The value returned is a pair of the 'Async' that completed, and the@@ -409,7 +404,7 @@ -- -- @since 1.1.1.0 waitAnyCatchSTM :: MonadConc m => [Async m a] -> STM m (Async m a, Either SomeException a)-waitAnyCatchSTM = foldr (orElse . (\a -> do r <- waitCatchSTM a; return (a, r))) retry+waitAnyCatchSTM = foldr (orElse . (\a -> do r <- waitCatchSTM a; pure (a, r))) retry  -- | Like 'waitAny', but also cancels the other asynchronous -- operations as soon as one has completed.@@ -503,7 +498,7 @@ waitBothSTM left right = do   a <- waitSTM left `orElse` (waitSTM right >> retry)   b <- waitSTM right-  return (a, b)+  pure (a, b)   -------------------------------------------------------------------------------@@ -521,7 +516,7 @@     r <- atomically w     case r of       Left e -> throwTo me e-      _ -> return ()+      _ -> pure ()  -- | Link two @Async@s together, such that if either raises an -- exception, the same exception is re-thrown in the other @Async@.@@ -534,7 +529,7 @@     case r of       Left  (Left e) -> throwTo tr e       Right (Left e) -> throwTo tl e-      _ -> return ()+      _ -> pure ()  -- | Fork a thread that runs the supplied action, and if it raises an -- exception, re-runs the action.  The thread terminates only when the@@ -545,7 +540,7 @@         r <- (try :: MonadConc m => m a -> m (Either SomeException a)) $ restore action         case r of           Left _ -> go-          _      -> return ()+          _      -> pure ()   in fork go  @@ -567,7 +562,7 @@     e <- takeMVar m     case e of       Left ex -> throw ex-      Right r -> return r+      Right r -> pure r  -- | Like 'race', but the result is ignored. --@@ -593,8 +588,8 @@ -- @since 1.1.1.0 concurrently :: MonadConc m => m a -> m b -> m (a, b) concurrently left right = concurrently' left right (collect []) where-  collect [Left a, Right b] _ = return (a, b)-  collect [Right b, Left a] _ = return (a, b)+  collect [Left a, Right b] _ = pure (a, b)+  collect [Right b, Left a] _ = pure (a, b)   collect xs m = do     e <- takeMVar m     case e of@@ -633,7 +628,7 @@      stop -    return r+    pure r  -- | Maps a @MonadConc@-performing function over any @Traversable@ -- data type, performing all the @MonadConc@ actions concurrently, and
Control/Concurrent/Classy/CRef.hs view
@@ -80,7 +80,7 @@   -- memory barrier.   ) where -import Control.Monad.Conc.Class+import           Control.Monad.Conc.Class  -- | Mutate the contents of a @CRef@. --
Control/Concurrent/Classy/Chan.hs view
@@ -27,9 +27,9 @@   , writeList2Chan   ) where -import Control.Concurrent.Classy.MVar-import Control.Monad.Catch (mask_)-import Control.Monad.Conc.Class (MonadConc)+import           Control.Concurrent.Classy.MVar+import           Control.Monad.Catch            (mask_)+import           Control.Monad.Conc.Class       (MonadConc)  -- | 'Chan' is an abstract type representing an unbounded FIFO -- channel.
Control/Concurrent/Classy/MVar.hs view
@@ -48,8 +48,9 @@  , modifyMVarMasked  ) where -import Control.Monad.Catch (mask_, onException)-import Control.Monad.Conc.Class+import           Control.Monad.Catch      (mask_, onException)+import           Control.Monad.Conc.Class+import           Data.Maybe               (isJust)  -- | Swap the contents of a @MVar@, and return the value taken. This -- function is atomic only if there are no other producers fro this@@ -60,17 +61,18 @@ swapMVar cvar a = mask_ $ do   old <- takeMVar cvar   putMVar cvar a-  return old+  pure old  -- | Check if a @MVar@ is empty. --+-- The boolean value returned is just a snapshot of the state of the+-- @MVar@, it may have been emptied (or filled) by the time you+-- actually access it. Generally prefer 'tryPutMVar', 'tryTakeMVar',+-- and 'tryReadMVar'.+-- -- @since 1.0.0.0 isEmptyMVar :: MonadConc m => MVar m a -> m Bool-isEmptyMVar cvar = do-  val <- tryTakeMVar cvar-  case val of-    Just val' -> putMVar cvar val' >> return True-    Nothing   -> return False+isEmptyMVar = fmap isJust . tryReadMVar  -- | Operate on the contents of a @MVar@, replacing the contents after -- finishing. This operation is exception-safe: it will replace the@@ -85,7 +87,7 @@   out <- restore (f val) `onException` putMVar cvar val   putMVar cvar val -  return out+  pure out  -- | Like 'withMVar', but the @IO@ action in the second argument is -- executed with asynchronous exceptions masked.@@ -98,7 +100,7 @@   out <- f val `onException` putMVar cvar val   putMVar cvar val -  return out+  pure out  -- | An exception-safe wrapper for modifying the contents of a @MVar@. -- Like 'withMVar', 'modifyMVar' will replace the original contents of@@ -121,7 +123,7 @@   val <- takeMVar cvar   (val', out) <- restore (f val) `onException` putMVar cvar val   putMVar cvar val'-  return out+  pure out  -- | Like 'modifyMVar_', but the @IO@ action in the second argument is -- executed with asynchronous exceptions masked.@@ -141,4 +143,4 @@   val <- takeMVar cvar   (val', out) <- f val `onException` putMVar cvar val   putMVar cvar val'-  return out+  pure out
Control/Concurrent/Classy/QSem.hs view
@@ -15,8 +15,8 @@   , signalQSem   ) where -import Control.Concurrent.Classy.QSemN-import Control.Monad.Conc.Class (MonadConc)+import           Control.Concurrent.Classy.QSemN+import           Control.Monad.Conc.Class        (MonadConc)  -- | @QSem@ is a quantity semaphore in which the resource is acquired -- and released in units of one. It provides guaranteed FIFO ordering
Control/Concurrent/Classy/QSemN.hs view
@@ -16,10 +16,11 @@   , signalQSemN   ) where -import Control.Monad.Conc.Class (MonadConc)-import Control.Concurrent.Classy.MVar-import Control.Monad.Catch (mask_, onException, uninterruptibleMask_)-import Data.Maybe+import           Control.Concurrent.Classy.MVar+import           Control.Monad.Catch            (mask_, onException,+                                                 uninterruptibleMask_)+import           Control.Monad.Conc.Class       (MonadConc)+import           Data.Maybe  -- | 'QSemN' is a quantity semaphore in which the resource is aqcuired -- and released in units of one. It provides guaranteed FIFO ordering
Control/Concurrent/Classy/STM.hs view
@@ -17,12 +17,10 @@   , module Control.Concurrent.Classy.STM.TArray   ) where -import Control.Monad.STM.Class-import Control.Concurrent.Classy.STM.TVar-import Control.Concurrent.Classy.STM.TMVar-import Control.Concurrent.Classy.STM.TChan-import Control.Concurrent.Classy.STM.TQueue-import Control.Concurrent.Classy.STM.TBQueue-import Control.Concurrent.Classy.STM.TArray--{-# ANN module ("HLint: ignore Use import/export shortcut" :: String) #-}+import           Control.Concurrent.Classy.STM.TArray+import           Control.Concurrent.Classy.STM.TBQueue+import           Control.Concurrent.Classy.STM.TChan+import           Control.Concurrent.Classy.STM.TMVar+import           Control.Concurrent.Classy.STM.TQueue+import           Control.Concurrent.Classy.STM.TVar+import           Control.Monad.STM.Class
Control/Concurrent/Classy/STM/TArray.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}  -- | -- Module      : Control.Concurrent.Classy.STM.@@ -15,12 +16,12 @@ -- an @Eq@ constraint. module Control.Concurrent.Classy.STM.TArray (TArray) where -import Data.Array (Array, bounds)-import Data.Array.Base (listArray, arrEleBottom, unsafeAt, MArray(..),-                        IArray(numElements))-import Data.Ix (rangeSize)+import           Data.Array              (Array, bounds)+import           Data.Array.Base         (IArray(numElements), MArray(..),+                                          arrEleBottom, listArray, unsafeAt)+import           Data.Ix                 (rangeSize) -import Control.Monad.STM.Class+import           Control.Monad.STM.Class  -- | @TArray@ is a transactional array, supporting the usual 'MArray' -- interface for mutable arrays.
Control/Concurrent/Classy/STM/TBQueue.hs view
@@ -33,7 +33,7 @@   , isFullTBQueue   ) where -import Control.Monad.STM.Class+import           Control.Monad.STM.Class  -- | 'TBQueue' is an abstract type representing a bounded FIFO -- channel.@@ -113,7 +113,7 @@ peekTBQueue c = do   x <- readTBQueue c   unGetTBQueue c x-  return x+  pure x  -- | A version of 'peekTBQueue' which does not retry. Instead it -- returns @Nothing@ if no value is available.
Control/Concurrent/Classy/STM/TChan.hs view
@@ -32,7 +32,7 @@   , isEmptyTChan   ) where -import Control.Monad.STM.Class+import           Control.Monad.STM.Class  -- | 'TChan' is an abstract type representing an unbounded FIFO -- channel.@@ -125,7 +125,7 @@ dupTChan (TChan _ writeT) = do   hole   <- readTVar writeT   readT' <- newTVar hole-  return (TChan readT' writeT)+  pure (TChan readT' writeT)  -- | Put a data item back onto a channel, where it will be the next -- item read.
Control/Concurrent/Classy/STM/TMVar.hs view
@@ -29,9 +29,9 @@   , swapTMVar   ) where -import Control.Monad (liftM, when, unless)-import Control.Monad.STM.Class-import Data.Maybe (isJust, isNothing)+import           Control.Monad           (liftM, unless, when)+import           Control.Monad.STM.Class+import           Data.Maybe              (isJust, isNothing)  -- | A @TMVar@ is like an @MVar@ or a @mVar@, but using transactional -- memory. As transactions are atomic, this makes dealing with@@ -57,7 +57,7 @@ newTMVarN n a = do   let n' = if null n then "ctmvar" else "ctmvar-" ++ n   ctvar <- newTVarN n' $ Just a-  return $ TMVar ctvar+  pure (TMVar ctvar)  -- | Create a new empty 'TMVar'. --@@ -75,7 +75,7 @@ newEmptyTMVarN n = do   let n' = if null n then "ctmvar" else "ctmvar-" ++ n   ctvar <- newTVarN n' Nothing-  return $ TMVar ctvar+  pure (TMVar ctvar)  -- | Take the contents of a 'TMVar', or 'retry' if it is empty. --@@ -83,7 +83,7 @@ takeTMVar :: MonadSTM stm => TMVar stm a -> stm a takeTMVar ctmvar = do   taken <- tryTakeTMVar ctmvar-  maybe retry return taken+  maybe retry pure taken  -- | Write to a 'TMVar', or 'retry' if it is full. --@@ -99,7 +99,7 @@ readTMVar :: MonadSTM stm => TMVar stm a -> stm a readTMVar ctmvar = do   readed <- tryReadTMVar ctmvar-  maybe retry return readed+  maybe retry pure readed  -- | Try to take the contents of a 'TMVar', returning 'Nothing' if it -- is empty.@@ -109,7 +109,7 @@ tryTakeTMVar (TMVar ctvar) = do   val <- readTVar ctvar   when (isJust val) $ writeTVar ctvar Nothing-  return val+  pure val  -- | Try to write to a 'TMVar', returning 'False' if it is full. --@@ -118,7 +118,7 @@ tryPutTMVar (TMVar ctvar) a = do   val <- readTVar ctvar   when (isNothing val) $ writeTVar ctvar (Just a)-  return $ isNothing val+  pure (isNothing val)  -- | Try to read from a 'TMVar' without emptying, returning 'Nothing' -- if it is empty.@@ -141,4 +141,4 @@ swapTMVar ctmvar a = do   val <- takeTMVar ctmvar   putTMVar ctmvar a-  return val+  pure val
Control/Concurrent/Classy/STM/TQueue.hs view
@@ -36,7 +36,7 @@   , isEmptyTQueue   ) where -import Control.Monad.STM.Class+import           Control.Monad.STM.Class  -- | 'TQueue' is an abstract type representing an unbounded FIFO channel. --
Control/Concurrent/Classy/STM/TVar.hs view
@@ -25,9 +25,9 @@   , registerDelay   ) where -import Control.Monad.STM.Class-import Control.Monad.Conc.Class-import Data.Functor (void)+import           Control.Monad.Conc.Class+import           Control.Monad.STM.Class+import           Data.Functor             (void)  -- * @TVar@s @@ -54,7 +54,7 @@ swapTVar ctvar a = do   old <- readTVar ctvar   writeTVar ctvar a-  return old+  pure old  -- | Set the value of returned 'TVar' to @True@ after a given number -- of microseconds. The caveats associated with 'threadDelay' also
Control/Monad/Conc/Class.hs view
@@ -66,32 +66,32 @@   ) where  -- for the class and utilities-import Control.Exception (Exception, AsyncException(ThreadKilled), SomeException)-import Control.Monad.Catch (MonadCatch, MonadThrow, MonadMask)-import qualified Control.Monad.Catch as Ca-import Control.Monad.STM.Class (MonadSTM, TVar, readTVar)-import Control.Monad.Trans.Control (MonadTransControl, StT, liftWith)-import Data.Proxy (Proxy(..))+import           Control.Exception            (AsyncException(ThreadKilled),+                                               Exception, SomeException)+import           Control.Monad.Catch          (MonadCatch, MonadMask,+                                               MonadThrow)+import qualified Control.Monad.Catch          as Ca+import           Control.Monad.STM.Class      (MonadSTM, TVar, readTVar)+import           Control.Monad.Trans.Control  (MonadTransControl, StT, liftWith)+import           Data.Proxy                   (Proxy(..))  -- for the 'IO' instance-import qualified Control.Concurrent as IO-import qualified Control.Concurrent.STM.TVar as IO-import qualified Control.Monad.STM as IO-import qualified Data.Atomics as IO-import qualified Data.IORef as IO+import qualified Control.Concurrent           as IO+import qualified Control.Concurrent.STM.TVar  as IO+import qualified Control.Monad.STM            as IO+import qualified Data.Atomics                 as IO+import qualified Data.IORef                   as IO  -- for the transformer instances-import Control.Monad.Reader (ReaderT)-import Control.Monad.Trans (lift)-import Control.Monad.Trans.Identity (IdentityT)-import qualified Control.Monad.RWS.Lazy as RL-import qualified Control.Monad.RWS.Strict as RS-import qualified Control.Monad.State.Lazy as SL-import qualified Control.Monad.State.Strict as SS-import qualified Control.Monad.Writer.Lazy as WL-import qualified Control.Monad.Writer.Strict as WS--{-# ANN module ("HLint: ignore Use const" :: String) #-}+import           Control.Monad.Reader         (ReaderT)+import qualified Control.Monad.RWS.Lazy       as RL+import qualified Control.Monad.RWS.Strict     as RS+import qualified Control.Monad.State.Lazy     as SL+import qualified Control.Monad.State.Strict   as SS+import           Control.Monad.Trans          (lift)+import           Control.Monad.Trans.Identity (IdentityT)+import qualified Control.Monad.Writer.Lazy    as WL+import qualified Control.Monad.Writer.Strict  as WS  -- | @MonadConc@ is an abstraction over GHC's typical concurrency -- abstraction. It captures the interface of concurrency monads in@@ -167,11 +167,11 @@   -- | Fork a computation to happen concurrently. Communication may   -- happen over @MVar@s.   ---  -- > fork ma = forkWithUnmask (\_ -> ma)+  -- > fork ma = forkWithUnmask (const ma)   --   -- @since 1.0.0.0   fork :: m () -> m (ThreadId m)-  fork ma = forkWithUnmask (\_ -> ma)+  fork ma = forkWithUnmask (const ma)    -- | Like 'fork', but the child thread is passed a function that can   -- be used to unmask asynchronous exceptions. This function should@@ -202,11 +202,11 @@   -- implementation dependent. The int is interpreted modulo to the   -- total number of capabilities as returned by 'getNumCapabilities'.   ---  -- > forkOn c ma = forkOnWithUnmask c (\_ -> ma)+  -- > forkOn c ma = forkOnWithUnmask c (const ma)   --   -- @since 1.0.0.0   forkOn :: Int -> m () -> m (ThreadId m)-  forkOn c ma = forkOnWithUnmask c (\_ -> ma)+  forkOn c ma = forkOnWithUnmask c (const ma)    -- | Like 'forkWithUnmask', but the child thread is pinned to the   -- given CPU, as with 'forkOn'.@@ -477,7 +477,7 @@ -- -- @since 1.0.0.0 forkN :: MonadConc m => String -> m () -> m (ThreadId m)-forkN name ma = forkWithUnmaskN name (\_ -> ma)+forkN name ma = forkWithUnmaskN name (const ma)  -- | Like 'forkOn', but the thread is given a name which may be used -- to present more useful debugging information.@@ -488,7 +488,7 @@ -- -- @since 1.0.0.0 forkOnN :: MonadConc m => String -> Int -> m () -> m (ThreadId m)-forkOnN name i ma = forkOnWithUnmaskN name i (\_ -> ma)+forkOnN name i ma = forkOnWithUnmaskN name i (const ma)  -- Bound Threads 
Control/Monad/STM/Class.hs view
@@ -31,21 +31,21 @@   , liftedOrElse   ) where -import Control.Exception (Exception)-import Control.Monad (unless)-import Control.Monad.Reader (ReaderT)-import Control.Monad.Trans (lift)-import Control.Monad.Trans.Control (MonadTransControl, StT, liftWith)-import Control.Monad.Trans.Identity (IdentityT)+import           Control.Exception            (Exception)+import           Control.Monad                (unless)+import           Control.Monad.Reader         (ReaderT)+import           Control.Monad.Trans          (lift)+import           Control.Monad.Trans.Control  (MonadTransControl, StT, liftWith)+import           Control.Monad.Trans.Identity (IdentityT) -import qualified Control.Concurrent.STM as STM-import qualified Control.Monad.Catch as Ca-import qualified Control.Monad.RWS.Lazy as RL-import qualified Control.Monad.RWS.Strict as RS-import qualified Control.Monad.State.Lazy as SL-import qualified Control.Monad.State.Strict as SS-import qualified Control.Monad.Writer.Lazy as WL-import qualified Control.Monad.Writer.Strict as WS+import qualified Control.Concurrent.STM       as STM+import qualified Control.Monad.Catch          as Ca+import qualified Control.Monad.RWS.Lazy       as RL+import qualified Control.Monad.RWS.Strict     as RS+import qualified Control.Monad.State.Lazy     as SL+import qualified Control.Monad.State.Strict   as SS+import qualified Control.Monad.Writer.Lazy    as WL+import qualified Control.Monad.Writer.Strict  as WS  -- | @MonadSTM@ is an abstraction over 'STM'. --
+ README.markdown view
@@ -0,0 +1,67 @@+concurrency+===========++A typeclass abstraction over much of Control.Concurrent (and some+extras!). If you're looking for a general introduction to Haskell+concurrency, you should check out the excellent+[Parallel and Concurrent Programming in Haskell][parconc], by Simon+Marlow. If you are already familiar with concurrent Haskell, just+change all the imports from Control.Concurrent.* to+Control.Concurrent.Classy.* and fix the type errors.++A brief list of supported functionality:++- Threads: the `forkIO*` and `forkOn*` functions, although bound+  threads are not supported.+- Getting and setting capablities.+- Yielding and delaying.+- Mutable state: STM, `MVar`, and `IORef`.+- Atomic compare-and-swap for `IORef`.+- Exceptions.+- All of the data structures in Control.Concurrent.* and+  Control.Concurrent.STM.* have typeclass-abstracted equivalents.+- A reimplementation of the [async][] package, providing a+  higher-level interface over threads, allowing users to conveniently+  run `MonadConc` operations asynchronously and wait for their+  results.++This is quite a rich set of functionality, although it is not+complete. If there is something else you need, file an issue!++This used to be part of dejafu, but with the dejafu-0.4.0.0 release,+it was split out into its own package.++The documentation of the latest developmental version is+[available online][docs].++Why this and not something else?+--------------------------------++- **Why not base:** like lifted-base, concurrency uses typeclasses to+  make function types more generic. This automatically eliminates+  calls to `lift` in many cases, resulting in clearer and simpler+  code.++- **Why not lifted-base:** fundamentally, lifted-base is still using+  actual threads and actual mutable variables. When using a+  concurrency-specific typeclass, this isn't necessarily the case. The+  dejafu library provides non-IO-based implementations to allow+  testing concurrent programs.++- **Why not IOSpec:** IOSpec provides many of the operations this+  library does, however it uses a free monad to do so, which has extra+  allocation overhead. Furthermore, it does not expose enough of the+  internals in order to accurately test real-execution semantics, such+  as relaxed memory.++Contributing+------------++Bug reports, pull requests, and comments are very welcome!++Feel free to contact me on GitHub, through IRC (#haskell on freenode),+or email (mike@barrucadu.co.uk).++[docs]:    https://docs.barrucadu.co.uk/concurrency/dejafu-0.4+[async]:   https://hackage.haskell.org/package/async+[parconc]: http://chimera.labs.oreilly.com/books/1230000000929
Setup.hs view
@@ -1,2 +1,2 @@-import Distribution.Simple+import           Distribution.Simple main = defaultMain
concurrency.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                concurrency-version:             1.1.2.0+version:             1.1.2.1 synopsis:            Typeclasses, functions, and data types for concurrency and STM.  description:@@ -13,58 +13,6 @@   already familiar with concurrent Haskell, just change all the   imports from Control.Concurrent.* to Control.Concurrent.Classy.* and   fix the type errors.-  .-  A brief list of supported functionality:-  .-  * Threads: the @forkIO*@ and @forkOn*@ functions, although bound-    threads are not supported.-  .-  * Getting and setting capablities.-  .-  * Yielding and delaying.-  .-  * Mutable state: STM, @MVar@, and @IORef@.-  .-  * Atomic compare-and-swap for @IORef@.-  .-  * Exceptions.-  .-  * All of the data structures in Control.Concurrent.* and-    Control.Concurrent.STM.* have typeclass-abstracted equivalents.-  .-  * A reimplementation of the-    <https://hackage.haskell.org/package/async async> package,-    providing a higher-level interface over threads, allowing users to-    conveniently run @MonadConc@ operations asynchronously and wait-    for their results.-  .-  This is quite a rich set of functionality, although it is not-  complete. If there is something else you need, file an issue!-  .-  This used to be part of dejafu, but with the dejafu-0.4.0.0 release,-  it was split out into its own package.-  .-  == Why this and not something else?-  .-  * Why not base: like lifted-base, concurrency uses typeclasses to-    make function types more generic. This automatically eliminates-    calls to `lift` in many cases, resulting in clearer and simpler-    code.-  .-  * Why not lifted-base: fundamentally, lifted-base is still using-    actual threads and actual mutable variables. When using a-    concurrency-specific typeclass, this isn't necessarily the case.-    The dejafu library provides non-IO-based implementations to allow-    testing concurrent programs.-  .-  * Why not IOSpec: IOSpec provides many of the operations this-    library does, however it uses a free monad to do so, which has-    extra allocation overhead. Furthermore, it does not expose enough-    of the internals in order to accurately test real-execution-    semantics, such as relaxed memory.-  .-  See the <https://github.com/barrucadu/dejafu README> for more-  details.  homepage:            https://github.com/barrucadu/dejafu license:             MIT@@ -74,7 +22,7 @@ -- copyright:            category:            Concurrency build-type:          Simple--- extra-source-files:  +extra-source-files:  README.markdown CHANGELOG.markdown cabal-version:       >=1.10  source-repository head@@ -84,7 +32,7 @@ source-repository this   type:     git   location: https://github.com/barrucadu/dejafu.git-  tag:      concurrency-1.1.2.0+  tag:      concurrency-1.1.2.1  library   exposed-modules:     Control.Monad.Conc.Class