@@ -36,7 +36,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3636OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3737-}
3838
39- {-# LANGUAGE MagicHash, UnboxedTuples #-}
39+ {-# LANGUAGE CPP, MagicHash, UnboxedTuples #-}
4040
4141module Control.Concurrent.Async (
4242 async , withAsync , wait , asyncThreadId , cancel , concurrently
@@ -51,6 +51,19 @@ import GHC.Conc (ThreadId(..))
5151import GHC.Exts
5252import GHC.IO hiding (onException )
5353
54+ #if !MIN_VERSION_base(4,21,0)
55+ type ExceptionWithContext x = x
56+
57+ catchNoPropagate :: IO a -> (ExceptionWithContext SomeException -> IO a ) -> IO a
58+ catchNoPropagate = catchAll
59+
60+ tryWithContext :: IO a -> IO (Either (ExceptionWithContext SomeException ) a )
61+ tryWithContext = try
62+
63+ rethrowIO :: ExceptionWithContext SomeException -> IO a
64+ rethrowIO = throwIO
65+ #endif
66+
5467-- | An asynchronous action spawned by 'async' or 'withAsync'.
5568-- Asynchronous actions are executed in a separate thread, and
5669-- operations are provided for waiting for asynchronous actions to
@@ -60,7 +73,7 @@ data Async a = Async
6073 { asyncThreadId :: {-# UNPACK #-} ! ThreadId
6174 -- ^ Returns the t'ThreadId' of the thread running
6275 -- the given t'Async'.
63- , _asyncWait :: STM (Either SomeException a )
76+ , _asyncWait :: STM (Either ( ExceptionWithContext SomeException ) a )
6477 }
6578
6679-- | Spawn an asynchronous action in a separate thread.
@@ -102,11 +115,11 @@ withAsyncUsing :: (IO () -> IO ThreadId)
102115withAsyncUsing doFork = \ action inner -> do
103116 var <- newEmptyTMVarIO
104117 mask $ \ restore -> do
105- t <- doFork $ try (restore action) >>= atomically . putTMVar var
118+ t <- doFork $ tryWithContext (restore action) >>= atomically . putTMVar var
106119 let a = Async t (readTMVar var)
107- r <- restore (inner a) `catchAll ` \ e -> do
120+ r <- restore (inner a) `catchNoPropagate ` \ e -> do
108121 uninterruptibleCancel a
109- throwIO e
122+ rethrowIO (e :: ExceptionWithContext SomeException )
110123 uninterruptibleCancel a
111124 return r
112125
@@ -130,7 +143,7 @@ wait = tryAgain . atomically . waitSTM
130143-- > waitCatch = atomically . waitCatchSTM
131144--
132145{-# INLINE waitCatch #-}
133- waitCatch :: Async a -> IO (Either SomeException a )
146+ waitCatch :: Async a -> IO (Either ( ExceptionWithContext SomeException ) a )
134147waitCatch = tryAgain . atomically . waitCatchSTM
135148 where
136149 -- See: https://github.com/simonmar/async/issues/14
@@ -146,7 +159,7 @@ waitSTM a = do
146159-- | A version of 'waitCatch' that can be used inside an STM transaction.
147160--
148161{-# INLINE waitCatchSTM #-}
149- waitCatchSTM :: Async a -> STM (Either SomeException a )
162+ waitCatchSTM :: Async a -> STM (Either ( ExceptionWithContext SomeException ) a )
150163waitCatchSTM (Async _ w) = w
151164
152165-- | Cancel an asynchronous action by throwing the @AsyncCancelled@
0 commit comments