#7170: Foreign.Concurrent finalizer called twice in some cases ------------------------------+--------------------------------------------- Reporter: joeyadams | Owner: Type: bug | Status: new Priority: normal | Component: Runtime System Version: 7.4.2 | Keywords: Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Runtime crash | Testcase: Blockedby: | Blocking: Related: | ------------------------------+---------------------------------------------
Comment(by joeyadams): I'm guessing that the problem is in this function from {{{GHC.ForeignPtr}}}: {{{ foreignPtrFinalizer :: IORef (Finalizers, [IO ()]) -> IO () foreignPtrFinalizer r = do (_, fs) <- readIORef r; sequence_ fs }}} This invokes the finalizers, but does not empty out the list. When the application calls finalizeForeignPtr later, the same list of finalizers is run again. While we're at it, this really bothers me: {{{ finalizeForeignPtr (ForeignPtr _ foreignPtr) = do (ftype, finalizers) <- readIORef refFinalizers sequence_ finalizers writeIORef refFinalizers (ftype, []) }}} This isn't thread safe or exception safe. Finalizers can be repeated if another thread comes along and calls finalizeForeignPtr on the same pointer, or if a finalizer throws an exception. A reasonable solution might be to wrap incoming finalizers with this: {{{ once :: IO () -> IO (IO ()) once io = do mv <- newMVar io return $ tryTakeMVar mv >>= maybe (return ()) id }}} This way, we don't have to worry about finalizers being called twice. -- Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7170#comment:1> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler _______________________________________________ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs