Proposed change to ForeignPtr
ger at tzi.de
Tue Sep 10 16:34:27 EDT 2002
Alastair Reid wrote:
> You ask how garbage collection can work if you can't invoke it at
> arbitrary times? You ask what use foreign export is if you can't call
> the exported function at arbitrary times?
> [I hope I'm paraphrasing your questions appropriately]
> Both questions start by assuming that you have Haskell and Foosh [or
> whatever your other language is called] running in separate threads
> (otherwise things wouldn't happen at arbitrary times). Put them in a
> single thread and there's no problem: you're not doing things at
> arbitrary times, you're doing them at quite specific times: Foosh had
> control and it called into Haskell or Haskell had control and it
> called into Foosh.
No, you do not really need separate threads for this problem to occur.
All you need is, say, Hugs to call a GHC-exported function as a finalizer,
in the same OS thread, GHC to run a garbage collection during this function,
and the garbage collection in turn to want to run a Hugs finalizer, before
the finalizer called from Hugs has finished. Of course one wouldn't normally
want to link GHC from Hugs, but if even these two cannot be made to meet, I
don't know how you expect Haskell to call anything else with a reasonably
flexible GC system; it puts the kybosh on Java for example, which I am fairly
sure makes plenty of use of both callbacks and finalizers.
In any case it seems to me just as dangerous to assume that the implementation
does not use OS threads, as to assume it does. You are effectively writing on
top of the FFI document "If your program does this perfectly reasonable combination
of finalizers, it will fall over in an undefined way should the implementation
use OS threads; furthermore there is no way around this". Basically the fact
that there is only one OS thread is an implementation detail, not something that
the user should have to think about.
Is it really the case that neither NHC nor Hugs can implement a list of actions to
be taken at the first convenient point after GC has finished without implementing the
whole machinery of preemptive concurrency? I take Malcolm Wallace's word for it
that it isn't trivial, but why do you need for example asynchronous interruption of
Haskell threads, wait queues, or time slices? Surely what you need is some way of
backing up the state upon return from GC in such a way that you can run the queued
IO actions, which may be hard but is a long way off preemptive concurrency.
If it's really impossible for NHC or Hugs to implement this, I think I would still
rather it was left to the NHC and Hugs documentation to admit that exported Haskell
functions basically don't work in some circumstances, rather than to the GHC documentation
to say that actually they do.
More information about the FFI