async 2.2.1 → 2.2.2
raw patch · 4 files changed
+48/−15 lines, 4 filesdep ~basedep ~hashablePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: base, hashable
API changes (from Hackage documentation)
- Control.Concurrent.Async: instance GHC.Exception.Exception Control.Concurrent.Async.AsyncCancelled
- Control.Concurrent.Async: instance GHC.Exception.Exception Control.Concurrent.Async.ExceptionInLinkedThread
+ Control.Concurrent.Async: instance GHC.Exception.Type.Exception Control.Concurrent.Async.AsyncCancelled
+ Control.Concurrent.Async: instance GHC.Exception.Type.Exception Control.Concurrent.Async.ExceptionInLinkedThread
+ Control.Concurrent.Async: link2Only :: (SomeException -> Bool) -> Async a -> Async b -> IO ()
+ Control.Concurrent.Async: linkOnly :: (SomeException -> Bool) -> Async a -> IO ()
- Control.Concurrent.Async: ExceptionInLinkedThread :: (Async a) -> SomeException -> ExceptionInLinkedThread
+ Control.Concurrent.Async: ExceptionInLinkedThread :: Async a -> SomeException -> ExceptionInLinkedThread
Files
- Control/Concurrent/Async.hs +26/−11
- async.cabal +4/−4
- changelog.md +7/−0
- test/test-async.hs +11/−0
Control/Concurrent/Async.hs view
@@ -117,7 +117,7 @@ waitBothSTM, -- ** Linking- link, link2, ExceptionInLinkedThread(..),+ link, linkOnly, link2, link2Only, ExceptionInLinkedThread(..), -- * Convenient utilities race, race_,@@ -185,7 +185,7 @@ instance Functor Async where fmap f (Async a w) = Async a (fmap (fmap f) w) --- | Compare two 'Async's that may have different types+-- | Compare two Asyncs that may have different types by their ThreadId. compareAsyncs :: Async a -> Async b -> Ordering compareAsyncs (Async t1 _) (Async t2 _) = compare t1 t2 @@ -230,7 +230,7 @@ -- -- > withAsync action inner = mask $ \restore -> do -- > a <- async (restore action)--- > restore inner `finally` uninterruptibleCancel a+-- > restore (inner a) `finally` uninterruptibleCancel a -- -- This is a useful variant of 'async' that ensures an @Async@ is -- never left running unintentionally.@@ -289,7 +289,10 @@ -- {-# INLINE wait #-} wait :: Async a -> IO a-wait = atomically . waitSTM+wait = tryAgain . atomically . waitSTM+ where+ -- See: https://github.com/simonmar/async/issues/14+ tryAgain f = f `catch` \BlockedIndefinitelyOnSTM -> f -- | Wait for an asynchronous action to complete, and return either -- @Left e@ if the action raised an exception @e@, or @Right a@ if it@@ -537,8 +540,12 @@ #endif instance Show ExceptionInLinkedThread where- show (ExceptionInLinkedThread (Async t _) e) =- "ExceptionInLinkedThread " ++ show t ++ " " ++ show e+ showsPrec p (ExceptionInLinkedThread (Async t _) e) =+ showParen (p >= 11) $+ showString "ExceptionInLinkedThread " .+ showsPrec 11 t .+ showString " " .+ showsPrec 11 e instance Exception ExceptionInLinkedThread where #if __GLASGOW_HASKELL__ >= 708@@ -559,10 +566,11 @@ -- | Link the given @Async@ to the current thread, such that if the -- @Async@ raises an exception, that exception will be re-thrown in--- the current thread. The supplied predicate determines which--- exceptions in the target thread should be propagated to the source--- thread.+-- the current thread, wrapped in 'ExceptionInLinkedThread'. --+-- The supplied predicate determines which exceptions in the target+-- thread should be propagated to the source thread.+-- linkOnly :: (SomeException -> Bool) -- ^ return 'True' if the exception -- should be propagated, 'False'@@ -588,6 +596,13 @@ link2 :: Async a -> Async b -> IO () link2 = link2Only (not . isCancel) +-- | Link two @Async@s together, such that if either raises an+-- exception, the same exception is re-thrown in the other @Async@,+-- wrapped in 'ExceptionInLinkedThread'.+--+-- The supplied predicate determines which exceptions in the target+-- thread should be propagated to the source thread.+-- link2Only :: (SomeException -> Bool) -> Async a -> Async b -> IO () link2Only shouldThrow left@(Async tl _) right@(Async tr _) = void $ forkRepeat $ do@@ -755,12 +770,12 @@ forConcurrently = flip mapConcurrently -- | `mapConcurrently_` is `mapConcurrently` with the return value discarded,--- just like @mapM_+-- just like @mapM_@. mapConcurrently_ :: F.Foldable f => (a -> IO b) -> f a -> IO () mapConcurrently_ f = runConcurrently . F.foldMap (Concurrently . void . f) -- | `forConcurrently_` is `forConcurrently` with the return value discarded,--- just like @forM_+-- just like @forM_@. forConcurrently_ :: F.Foldable f => f a -> (a -> IO b) -> IO () forConcurrently_ = flip mapConcurrently_
async.cabal view
@@ -1,5 +1,5 @@ name: async-version: 2.2.1+version: 2.2.2 -- don't forget to update ./changelog.md! synopsis: Run IO operations asynchronously and wait for their results @@ -34,7 +34,7 @@ cabal-version: >=1.10 homepage: https://github.com/simonmar/async bug-reports: https://github.com/simonmar/async/issues-tested-with: GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2, GHC==7.2.2, GHC==7.0.4+tested-with: GHC==8.6.5, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2, GHC==7.2.2, GHC==7.0.4 extra-source-files: changelog.md@@ -50,14 +50,14 @@ if impl(ghc>=7.1) other-extensions: Trustworthy exposed-modules: Control.Concurrent.Async- build-depends: base >= 4.3 && < 4.12, hashable >= 1.1.1.0 && < 1.3, stm >= 2.2 && < 2.5+ build-depends: base >= 4.3 && < 4.14, hashable >= 1.1.2.0 && < 1.4, stm >= 2.2 && < 2.6 test-suite test-async default-language: Haskell2010 type: exitcode-stdio-1.0 hs-source-dirs: test main-is: test-async.hs- build-depends: base >= 4.3 && < 4.12,+ build-depends: base >= 4.3 && < 4.14, async, stm, test-framework,
changelog.md view
@@ -1,3 +1,10 @@+## Changes in 2.2.2:++ - Builds with GHC 8.6.x+ - linkOnly and link2Only are now exported+ - wait now has the same behaviour with BlockedIndefinitelyOnSTM as waitCatch+ - Documentation fixes+ ## Changes in 2.2.1: - Add a Hashable instance for Async
test/test-async.hs view
@@ -34,6 +34,7 @@ , testCase "async_poll" async_poll , testCase "async_poll2" async_poll2 , testCase "withasync_waitCatch_blocked" withasync_waitCatch_blocked+ , testCase "withasync_wait_blocked" withasync_wait_blocked , testGroup "children surviving too long" [ testCase "concurrently+success" concurrently_success , testCase "concurrently+failure" concurrently_failure@@ -140,6 +141,16 @@ withasync_waitCatch_blocked :: Assertion withasync_waitCatch_blocked = do r <- withAsync (newEmptyMVar >>= takeMVar) waitCatch+ case r of+ Left e ->+ case fromException e of+ Just BlockedIndefinitelyOnMVar -> return ()+ Nothing -> assertFailure $ show e+ Right () -> assertFailure ""++withasync_wait_blocked :: Assertion+withasync_wait_blocked = do+ r <- try $ withAsync (newEmptyMVar >>= takeMVar) wait case r of Left e -> case fromException e of