[GHC] #7787: modifyMVar does not restore value if callback returns error value

GHC cvs-ghc at haskell.org
Sat Mar 23 05:09:11 CET 2013


#7787: modifyMVar does not restore value if callback returns error value
----------------------------------------+-----------------------------------
Reporter:  joeyadams                    |          Owner:                  
    Type:  bug                          |         Status:  new             
Priority:  normal                       |      Component:  libraries/base  
 Version:  7.7                          |       Keywords:                  
      Os:  Unknown/Multiple             |   Architecture:  Unknown/Multiple
 Failure:  Incorrect result at runtime  |      Blockedby:                  
Blocking:                               |        Related:                  
----------------------------------------+-----------------------------------
 `modifyMVar` is currently implemented as follows:

 {{{
 modifyMVar :: MVar a -> (a -> IO (a,b)) -> IO b
 modifyMVar m io =
   mask $ \restore -> do
     a      <- takeMVar m
     (a',b) <- restore (io a) `onException` putMVar m a
     putMVar m a'
     return b
 }}}

 The problem is that it forces the `(a',b)` outside of the exception
 handler.  If forcing this throws an exception, `putMVar` will not be
 called, and a subsequent `withMVar` or similar will hang.  Example:

 {{{
 > import Control.Concurrent.MVar
 > mv <- newMVar 'x'
 > modifyMVar mv $ \_ -> return undefined
 *** Exception: Prelude.undefined
 > withMVar mv print
 -- hang --
 }}}

 Perhaps we can fix it like this:

 {{{
 -     (a',b) <- restore (io a) `onException` putMVar m a
 +     (a',b) <- restore (io a >>= evaluate) `onException` putMVar m a
 }}}

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



More information about the ghc-tickets mailing list