@@ -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,12 @@ import GHC.Conc (ThreadId(..))
5151import GHC.Exts
5252import GHC.IO hiding (onException )
5353
54+ #if MIN_VERSION_base(4,21,0)
55+ #define ExcWithContext(x) ExceptionWithContext (x)
56+ #else
57+ #define ExcWithContext(x) x
58+ #endif
59+
5460-- | An asynchronous action spawned by 'async' or 'withAsync'.
5561-- Asynchronous actions are executed in a separate thread, and
5662-- operations are provided for waiting for asynchronous actions to
@@ -60,7 +66,7 @@ data Async a = Async
6066 { asyncThreadId :: {-# UNPACK #-} ! ThreadId
6167 -- ^ Returns the t'ThreadId' of the thread running
6268 -- the given t'Async'.
63- , _asyncWait :: STM (Either SomeException a )
69+ , _asyncWait :: STM (Either ( ExcWithContext ( SomeException )) a )
6470 }
6571
6672-- | Spawn an asynchronous action in a separate thread.
@@ -102,11 +108,19 @@ withAsyncUsing :: (IO () -> IO ThreadId)
102108withAsyncUsing doFork = \ action inner -> do
103109 var <- newEmptyTMVarIO
104110 mask $ \ restore -> do
111+ #if MIN_VERSION_base(4,21,0)
112+ t <- doFork $ tryWithContext (restore action) >>= atomically . putTMVar var
113+ let a = Async t (readTMVar var)
114+ r <- restore (inner a) `catchNoPropagate` \ e -> do
115+ uninterruptibleCancel a
116+ rethrowIO (e :: ExceptionWithContext SomeException )
117+ #else
105118 t <- doFork $ try (restore action) >>= atomically . putTMVar var
106119 let a = Async t (readTMVar var)
107120 r <- restore (inner a) `catchAll` \ e -> do
108121 uninterruptibleCancel a
109122 throwIO e
123+ #endif
110124 uninterruptibleCancel a
111125 return r
112126
@@ -130,7 +144,7 @@ wait = tryAgain . atomically . waitSTM
130144-- > waitCatch = atomically . waitCatchSTM
131145--
132146{-# INLINE waitCatch #-}
133- waitCatch :: Async a -> IO (Either SomeException a )
147+ waitCatch :: Async a -> IO (Either ( ExcWithContext ( SomeException )) a )
134148waitCatch = tryAgain . atomically . waitCatchSTM
135149 where
136150 -- See: https://github.com/simonmar/async/issues/14
@@ -146,7 +160,7 @@ waitSTM a = do
146160-- | A version of 'waitCatch' that can be used inside an STM transaction.
147161--
148162{-# INLINE waitCatchSTM #-}
149- waitCatchSTM :: Async a -> STM (Either SomeException a )
163+ waitCatchSTM :: Async a -> STM (Either ( ExcWithContext ( SomeException )) a )
150164waitCatchSTM (Async _ w) = w
151165
152166-- | Cancel an asynchronous action by throwing the @AsyncCancelled@
0 commit comments