Some comments on the question of finalisers. Firstly, a retraction. In nhc98, it *is* possible to implement Haskell finalisers, by creating a `pending' list of finalisers during the GC, and then running them immediately the GC finishes. I see several messages in the archive where I claimed the latter was impossible. I was wrong. (The key issue is deciding when GC has really finished - not as obvious as it looks, but I got there in the end.)
What is more, I am now pretty convinced that it is relatively trivial to permit those finalisers to call foreign code that calls back into Haskell, possibly triggering a further GC, and for everything still to play nicely. (A mutex lock is required to ensure that the pending queue is not traversed more than once, but that is all I think.) At the moment nhc98 still has the ability, as per recent changes in the FFI spec, to call a foreign language finaliser (FunPtr (Ptr a -> IO ())) rather than a Haskell one. However, our GC currently calls such a finaliser immediately it finds it, i.e. in the middle of the GC cycle. I am now certain that this is wrong, because the foreign code could call back into Haskell, which of course would be disastrous in the middle of a GC. So just like with a Haskell finaliser, a foreign code finaliser must be placed on a `pending' list and run only after GC has finished. Hence, I think the really key issue for the safety of finalisers is not what language the finaliser is written in, but when it is run. Now, how about concurrency? nhc98 has no concurrency model, so all its interactions with foreign code must be within a single thread. This is true even if the foreign code has concurrent threads internally. Because nhc98 produces only sequential code, all interaction with the Haskell program must take place within that thread alone. The sequential Haskell RTS simply has to ensure is that when a Haskell GC is in progress, no foreign code can run in the same thread. (This is the reason for delaying any finalisers until the GC is complete.) For systems that do have concurrency, George points out that a concurrent foreign thread might call into Haskell at any moment, even when the Haskell RTS is in the middle of a GC. True enough. But this has nothing to do with finalisation per se, it is just a general feature of any concurrent system where there is a combination of languages. Just apply the usual mechanism in the Haskell RTS to exclude other activity during a GC. I understand that there are more tricky issues in concurrency, to do with shared access to resources, and scheduling policy. However I am still not sure of all the details, so Alastair's concerns are probably well-founded. I *think* the problem in Hugs is that the scheduler is co-operative, so the GC cannot simply place a triggered finaliser into a new thread and ignore it. (The co-operative scheduler might delay the running of the finaliser thread for an arbitrarily long time.) The GC also cannot make the triggered finaliser into a new thread and start running it immediately GC is finished. (This would amount to overriding the scheduler - pre-empting it in fact.) Is this a fair characterisation Alastair? If so, then I have two questions: (1) Why is it a disaster for a finaliser to be delayed for an arbitrary amount of time? As things stand, there is no guarantee on when a finaliser will run anyway, just that it will do so before the end of the computation. (2) Why is it a disaster to have an occasional change of scheduling policy (from co-operative multi-tasking to pre-emption)? Does it change the semantics of the concurrency model? Does it lead to a possible loss of termination? Does it disrupt some in-built assumptions in the runtime system? Regards, Malcolm _______________________________________________ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi