* Bertram Felgenhauer <[email protected]> [2013-07-28 18:11:54+0200] > 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?)
Fair point. What if we fork a new thread, shield it from exceptions using uninterruptibleMask_, and let it to kill every other thread (however long that may take)? It will change the semantics a bit (the cleanup will be asynchronous), but I'm not sure if it can be a problem. A hybrid (but complicated) approach should also be possible. Roman _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
