> I'm not sure if this is neccessary, because it is possible to have
> global (mutable!) variables via IORefs + unsafePerformIO:
> 
> blockingSem :: IORef QSem
> blockingSem = unsafePerformIO (newIORef =<< newQSem 1)
> 
> gtkMumbleFooBar :: ... -> IO ()
> gtkMumbleFooBar ... = do
>    ...
>    waitQSem =<< readIORef blockingSem
>    doObscureGTKStuff

Yes, we do this a lot.  It's such a useful thing
that I wonder whether we should support it more directly, 
somehow.  As it stands, its vulnerable to 'blockingSem'
getting inlined at its usage sites, which would be a total
disaster.  That's what you get with unsafePerformIO; we've even
added a {-# NOINLINE blockingSem #-} pragma for exactly this reason.
(Doubtless undocumented.)

I'd like to have a better design.

> But I've another callback-related question: How should adjustor thunks
> (aka Haskell callbacks) be freed? Assume the following scenario:
> 
>    1. Create a callback via the foreign export ccall mechanism.
>    2. Register it to the C-API (GTK+, GLUT, etc.)
>    3. After a while, the callback is called from C-land (following
>       obscure paths through the RTS laid out by Sigbjorn :-)
>    4. The callback wants to re-register a new callback for the same
>       event.
>    5. The running "old" callback can still do anything it pleases
>    6. The callback finishes

Is there a problem here?  Presumably you are using foreign
export dynamic for step (1).  To do step (2) you have to make the
callback into a stable pointer; that will keep it alive until
the stable pointer is explicitly freed.  In step (4) you can 
free the stable pointer to the old callback.  That doesn't cause
the thing to be garbage collected if it's still executing; it simply
means that the GC knows that there's no *external* pointer to it.

Or have I missed something?

Simon

Reply via email to