
On Tue, Jan 10, 2006 at 09:40:41AM +0000, Simon Marlow wrote:
John Meacham wrote:
Yeah. this is a major bug in ghc IMHO. I believe it has been fixed, but am unsure.
It hasn't been fixed, this is the current behaviour and it's likely to stay that way, I'm afraid.
We used to run finalizers on exit, but we stopped doing that for various reasons. Even when we did run finalizers on exit, we couldn't guarantee to run all of them.
oh, the bug I was refering to was not not running finalizers on exit (which makes sense) but rather not flushing file handles on exit. the implication being that flushing the file handles should be done via some other mechanism than the GC finalizer.
Since we can't rely on finalizers to run in general, some sort of 'atexit' routine is needed. (which would be a good addition to the standard libraries anyway)
You can implement atexit quite straightforwardly, if that's what you want.
exits = unsafePerformIO (newIORef []) :: IORef [IO ()] main = do_stuff `finally` (readIORef exits >>= sequence_ . reverse) atexit io = modifyIORef exits (io:)
The problem is that people would have to know to put that in main, so the atexit functionality could not be used from libraries. I am thinking something more akin to C's atexit(3) function provided by its standard libraries. a proposed interface would be module System.Exit -- append to the current System.Exit data AtExitHandle -- | add a routine to be called on program exit addHandle :: IO () -> IO AtExitHandle -- | remove a routine previously set to be run on program exit, this actios is idempotent. removeHandle :: AtExitHandle -> IO () -- | run and remove a routine atomically, guarenteed to run routine at most once, even if called multiple times runRemoveHandle :: AtExitHandle -> IO () so, hOpen will do an addHandle (hClose h) stowing the AtExitHandle and hClose will do a removeHandle on the AtExitHandle I will happily implement this, I have needed it on several occasions when working on real-world programs especially since the (correct) decision to not ensure finalizers are run. (like making sure the terminal mode is reset, or that certain resources (lock files, SYSV semaphores) are released) in addition, I would add a _exitWith to System.Exit as the obvious parallel to _exit(2). John -- John Meacham - ⑆repetae.net⑆john⑈