Finalizers etcetera

Alastair Reid alastair at reid-consulting-uk.ltd.uk
Thu Oct 10 03:18:09 EDT 2002


> OK, so the problem is to find a place in Hugs that is passed
> frequently enough, but at which the internal data structures are
> consistent.

> How about the start of primPass (called to enter the continuation
> argument of >>= in the IO monad)?  Seems like a safe place to do an
> IO action.  (I don't know why the IO furniture is primitive, but
> since it's there ...)  The top-level loop is presumably another safe
> place.

I don't think >>= is frequent enough.  Pure code that manipulates big
C objects (remember that image processing example of mine?) can
generate a lot of garbage C objects without once going into the IO
monad.

More importantly though, this does nothing at all to guarantee
atomicity of Haskell code that manipulates global variables.  Consider
a data structure consisting of a list of objects.  The main thread
might add to this list and do searches in the list and the finalizer
removes objects from the list:

  type State = IORef [Object]

  -- used by main
  newObject :: Object -> IO ()
  newObject o = do
    os <- readIORef state
    writeIORef state (o:os)

  -- used by finalizer
  killObject :: Object -> IO ()
  killObject o = do
    os <- readIORef state
    writeIORef state (filter (/= 0) os)

Some possible interleavings of the IO actions in these functions can
result in an object not being added to or removed from the object
list.  Debugging this would be next to impossible since it would be
hard to repeat.

-- 
Alastair Reid                 alastair at reid-consulting-uk.ltd.uk  
Reid Consulting (UK) Limited  http://www.reid-consulting-uk.ltd.uk/alastair/




More information about the FFI mailing list