Skip to content

Commit fb9bfd3

Browse files
committed
feat: withAsync does not wrap exception in the inner block with WhileWaiting
1 parent 6dad253 commit fb9bfd3

1 file changed

Lines changed: 22 additions & 1 deletion

File tree

Control/Concurrent/Async/Internal.hs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,26 @@ withAsyncOnWithUnmask ::
207207
withAsyncOnWithUnmask cpu actionWith =
208208
withAsyncUsing (rawForkOn cpu) (actionWith unsafeUnmask)
209209

210+
#if MIN_VERSION_base(4,21,0)
211+
withAsyncUsing ::
212+
CALLSTACK
213+
(IO () -> IO ThreadId) -> IO a -> (Async a -> IO b) -> IO b
214+
-- The bracket version works, but is slow. We can do better by
215+
-- hand-coding it:
216+
withAsyncUsing doFork action inner = do
217+
var <- newEmptyTMVarIO
218+
mask $ \restore -> do
219+
let action_plus = debugLabelMe >> action
220+
t <- doFork $ try (restore action_plus) >>= atomically . putTMVar var
221+
let a = Async t (readTMVar var)
222+
-- Using catch/no/propagate and rethrowIO, we do not wrap the exception
223+
-- with a `WhileWaiting`
224+
r <- restore (inner a) `catchNoPropagate` \e -> do
225+
uninterruptibleCancel a
226+
rethrowIO (e :: ExceptionWithContext SomeException)
227+
uninterruptibleCancel a
228+
return r
229+
#else
210230
withAsyncUsing ::
211231
CALLSTACK
212232
(IO () -> IO ThreadId) -> IO a -> (Async a -> IO b) -> IO b
@@ -220,9 +240,10 @@ withAsyncUsing doFork action inner = do
220240
let a = Async t (readTMVar var)
221241
r <- restore (inner a) `catchAll` \e -> do
222242
uninterruptibleCancel a
223-
rethrowIO' e
243+
throwIO e
224244
uninterruptibleCancel a
225245
return r
246+
#endif
226247

227248

228249
-- | This function attempts at rethrowing while keeping the context

0 commit comments

Comments
 (0)