> I haven't checked, but ... I checked, and your solution works. In the context of a larger program, getting NOLINE pragmas in all the right places would be challenging, wouldn't it?
I found a bug report on the GHC Trac [1] in which Simon explains the importance of evaluating the thunk before calling addFinalizer. (Otherwise the finalizer is added to the thunk.) This works: newThing :: IO Thing newThing = do x <- Thing `fmap` newIORef True return $ unsafePerformIO ( do x' <- evaluate x addFinalizer x' $ putStrLn "running finalizer" ) `seq` x If anyone can show me how to get rid of unsafePerformIO in there, that'd be great. Tried a few things to no avail. > Finalizers are tricky things, especially when combined with some of > GHC's optimisations. No kidding! [1] http://hackage.haskell.org/trac/ghc/ticket/5365 Mike Craig On Thu, Feb 16, 2012 at 4:15 PM, Ian Lynagh <ig...@earth.li> wrote: > On Thu, Feb 16, 2012 at 02:55:13PM -0600, Austin Seipp wrote: > > 64-bit GHC on OS X gives me this: > > > > $ ghc -fforce-recomp -threaded finalizer > > [1 of 1] Compiling Main ( finalizer.hs, finalizer.o ) > > Linking finalizer ... > > $ ./finalizer > > waiting ... > > done! > > waiting ... > > running finalizer > > done! > > > > However, it's a different story when `-O2` is specified: > > > > $ ghc -O2 -fforce-recomp -threaded finalizer > > [1 of 1] Compiling Main ( finalizer.hs, finalizer.o ) > > Linking finalizer ... > > $ ./finalizer > > waiting ... > > running finalizer > > done! > > waiting ... > > done! > > > > This smells like a bug. The stranger thing is that the GC will run the > > finalizer, but it doesn't reclaim the object? I'd think `readIORef` > > going after an invalidated pointer the GC reclaimed would almost > > certainly crash. > > The finalizer is attached to the Thing, not the IORef. I haven't > checked, but I assume that ioref gets inlined, so effectively (ioref x) > is evaluated early. If you change it to > > readIORef (ioref' x) >>= \ix -> ix `seq` return () > > and define > > {-# NOINLINE ioref' #-} > ioref' :: Thing -> IORef Bool > ioref' = ioref > > then you'll get the sort of output you expect. > > Finalizers are tricky things, especially when combined with some of > GHC's optimisations. > > > Thanks > Ian > > > _______________________________________________ > Glasgow-haskell-users mailing list > Glasgow-haskell-users@haskell.org > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users >
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users