[Haskell-cafe] Is withAsync absolutely safe?

Bertram Felgenhauer bertram.felgenhauer at googlemail.com
Sun Jul 28 18:11:54 CEST 2013


Roman Cheplyaka wrote:
> Can withAsync guarantee that its child will be terminated if the thread
> executing withAsync gets an exception?
> 
> To remind, here's an implementation of withAsync:
> 
>   withAsyncUsing :: (IO () -> IO ThreadId)
>                  -> IO a -> (Async a -> IO b) -> IO b
>   -- The bracket version works, but is slow.  We can do better by
>   -- hand-coding it:
>   withAsyncUsing doFork = \action inner -> do
>     var <- newEmptyTMVarIO
>     mask $ \restore -> do
>       t <- doFork $ try (restore action) >>= atomically . putTMVar var
>       let a = Async t (readTMVar var)
>       r <- restore (inner a) `catchAll` \e -> do cancel a; throwIO e
>       cancel a
>       return r
> 
> I am interested in the case when an exception arrives which transfers
> control to 'cancel', and then another exception arrives to the same
> thread. Even though 'catchAll' (which is a type-restricted synonym for
> catch) masks the exception handler, 'throwTo' inside 'cancel' is
> interruptible (as stated by the documentation).
> 
> Will this scenario lead to a thread leakage?

Yes. I guess that 'cancel' should use 'uninterruptibleMask_', but it's a
hard call to make (if an async action becomes unresponsive, do we want
to risk not being able to deliver any exceptions to the controlling
thread just because it wants to terminate the async action?)

Best regards,

Bertram




More information about the Haskell-Cafe mailing list