Proposal: Add Control.Concurrent.forkIOWithUnmask, deprecate forkIOUnmasked

Ticket: http://hackage.haskell.org/trac/ghc/ticket/4858 We added forkIOUnmasked as part of the new asynchronous exceptions API in base 4.3.0.0 (GHC 7.0.1). Unfortunately, forkIOUnmasked isn't very useful: the computation in the child thread is executed in the unmasked state, so the child doesn't have a way to reliably set up an exception handler before an asynchronous exception is raised. This proposal is to replace forkIOUnmasked with forkIOWithUnmask: -- | Like 'forkIO', but the child thread is passed a function that can -- be used to unmask asynchronous exceptions. This function is -- typically used in the following way -- -- > ... mask_ $ forkIOWithUnmask $ \unmask -> -- > catch (unmask ...) handler -- -- so that the exception handler in the child thread is established -- with asynchronous exceptions masked, meanwhile the main body of -- the child thread is executed in the unmasked state. -- -- Note that the unmask function passed to the child thread should -- only be used in that thread; the behaviour is undefined if it is -- invoked in a different thread. -- forkIOWithUnmask :: ((forall a . IO a -> IO a) -> IO ()) -> IO ThreadId forkIOWithUnmask io = forkIO (io unsafeUnmask) forkIOUnmasked will be deprecated. Above is almost the entire implementation, hence I didn't bother attaching a patch to the ticket. Some discussion leading up to this can be found in http://hackage.haskell.org/trac/ghc/ticket/3837. Discussion period: 3 weeks (until 12 Jan 2011) Cheers, Simon

On 22/12/2010 10:50, Simon Marlow wrote:
Some discussion leading up to this can be found in http://hackage.haskell.org/trac/ghc/ticket/3837.
Oops, I meant http://hackage.haskell.org/trac/ghc/ticket/4810

On Wed, Dec 22, 2010 at 11:50 AM, Simon Marlow
This proposal is to replace forkIOUnmasked with forkIOWithUnmask:
+1 forkIOUnmasked was also difficult to wrap in my threads[1] library. I had to use the deprecated block and unblock operations to implement it: {-# OPTIONS_GHC -fno-warn-warnings-deprecations #-} -- For block and unblock forkIOUnmasked ∷ IO α → IO (ThreadId, IO (Result α)) forkIOUnmasked a = do res ← newEmptyMVar tid ← block $ Control.Concurrent.forkIO $ try (unblock a) >>= putMVar res return (tid, readMVar res) I don't need to use deprecated functions to wrap forkIOWithUnmask: forkIOWithUnmask ∷ ((∀ α. IO α → IO α) → IO α) → IO (ThreadId, IO (Result α)) forkIOWithUnmask io = do res ← newEmptyMVar tid ← mask_ $ Control.Concurrent.forkIOWithUnmask $ \restore → try (io restore) >>= putMVar res return (tid, readMVar res) Regards, Bas [1] http://hackage.haskell.org/packages/archive/threads/0.4/doc/html/Control-Con...
participants (2)
-
Bas van Dijk
-
Simon Marlow