[GHC] #7787: modifyMVar does not restore value if callback returns error value
#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
#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: ----------------------------------------+----------------------------------- Comment(by ezyang): Another possibility is to replace the pattern match with an irrefutable pattern. I'm not sure which is better, though an irrefutable pattern could make laziness bugs worse. -- Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7787#comment:1> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#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: ----------------------------------------+----------------------------------- Changes (by PHO): * cc: pho@… (added) -- Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7787#comment:2> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#7787: modifyMVar does not restore value if callback returns error value ---------------------------------+------------------------------------------ Reporter: joeyadams | Owner: Type: bug | Status: new Priority: high | Milestone: 7.8.1 Component: libraries/base | Version: 7.7 Keywords: | Os: Unknown/Multiple Architecture: Unknown/Multiple | Failure: Incorrect result at runtime Difficulty: Unknown | Testcase: Blockedby: | Blocking: Related: | ---------------------------------+------------------------------------------ Changes (by igloo): * priority: normal => high * difficulty: => Unknown * milestone: => 7.8.1 -- Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7787#comment:3> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#7787: modifyMVar does not restore value if callback returns error value ---------------------------------+------------------------------------------ Reporter: joeyadams | Owner: Type: bug | Status: new Priority: high | Milestone: 7.8.1 Component: libraries/base | Version: 7.7 Keywords: | Os: Unknown/Multiple Architecture: Unknown/Multiple | Failure: Incorrect result at runtime Difficulty: Unknown | Testcase: Blockedby: | Blocking: Related: | ---------------------------------+------------------------------------------ Comment(by parcs): Replying to [comment:1 ezyang]:
Another possibility is to replace the pattern match with an irrefutable pattern. I'm not sure which is better, though an irrefutable pattern could make laziness bugs worse.
Btw this is what `atomicModifyIORef` essentially does. -- Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7787#comment:4> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
participants (2)
-
GHC -
GHC