[GHC] #4810: Versions of bracket without masking acquire action

GHC cvs-ghc at haskell.org
Wed Dec 1 16:33:47 CET 2010


#4810: Versions of bracket without masking acquire action
---------------------------------+------------------------------------------
    Reporter:  mitar             |        Owner:              
        Type:  proposal          |       Status:  new         
    Priority:  normal            |    Milestone:              
   Component:  libraries/base    |      Version:  7.0.1       
    Keywords:                    |     Testcase:              
   Blockedby:                    |   Difficulty:              
          Os:  Unknown/Multiple  |     Blocking:              
Architecture:  Unknown/Multiple  |      Failure:  None/Unknown
---------------------------------+------------------------------------------

Comment(by simonmar):

 Replying to [comment:2 mitar]:
 > As I see there are two possibilities. We can add a version of `bracket`
 where actions gets as an argument `restore` function. So that they can
 `restore` it inside, for example they can have internally more `bracket`s,
 which make sure things are not acquired if exception is raised, but that
 exception can still be raised in a lengthy acquire.

 So you're saying you want something like:

 {{{
   bracket (do bracket a b c; d) e f
 }}}

 but can't you just transform that to

 {{{
   do bracket a b c
      bracket d e f
 }}}

 ?

 > The other, which I opted for above, is that we unmask acquire and then
 user can call `mask` immediately at the beginning of the acquire action,
 thus having a `restore` for use somewhere later. This short period of non-
 masked state is not a problem as nothing has yet been really acquired at
 the beginning of the acquire action.

 That wouldn't be safe either, because there would be a window at the end
 of the acquire action with exceptions unblocked.

 > My code where I require something like this is (simplified):
 >
 > {{{
 > bracketOnErrorUnmasked createThread killThread doSomethingWithThread
 >
 > createThread = mask $ \restore -> do
 >   -- do some preparations
 >   forkIO $ bracket prepareThread cleanupThreadAndFillMVar (restore
 doThreadAction)
 > }}}

 Right, so here you can receive an exception after the `forkIO`, and
 `doSomethingWithThread` will not be executed.


 > `forkIOUnmasked` does not help here because then there is a short period
 of time when `cleanupThreadAndFillMVar` will not be called (before
 internal `bracket` is initialized) so my program could hang waiting for
 `MVar` from a thread. And I want `doThreadAction` to be unmasked as
 otherwise thread is killable only in interruptible actions.

 Correct. I now realise that `forkIOUnmasked` is not really what we wanted;
 what we really should have added was

 {{{
 forkIOWithUnmask :: ((forall a. IO a -> IO a) -> IO a) -> IO ThreadId
 }}}

 Wouldn't that solve your problem?

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4810#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler



More information about the Glasgow-haskell-bugs mailing list