[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

Another possibility is to replace the pattern match with an irrefutable
#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]: 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