[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