> I just reread Dima's answer to my query about the database access in
> particular and am confused.  Dima says that he can't allow queries
> outside the IOMonad because he has to worry about freeing memory (query
> output).  
> 
> However, Haskell/Com (built on top of Greencard?) seems to be able to
> propagate garbage collection information from Haskell to C so that
> when a Haskell/COM Object is no longer in use, there is some functionality
> decrements its reference counter automatically.
> 
> How does this work?  and can dima use this mechamism to free queries
> when they are no longer needed? ..allowing database queries outside
> the IOMonad? 

The year before I left Glasgow, I added some special GC extensions to GHC.
When I arrived here, I added the same stuff into Hugs.
The details are in a never-completed paper which is hanging off my home
page (URL in signature) but here's an outline:

  ForeignPtrs (nee MallocPtrs) point from Haskell into C
  StablePtrs point from C into Haskell

ForeignPtr is just like Addr (the GHC/Hugs name for void*) except that
when the garbage collector deletes a ForeignPtr it calls a deallocation
function to let C know what's happening.  This deallocation function
might be "free" if the ForeignPtr is a block of memory or it might be
"fclose" if it's a FILE* or it might be a piece of code you wrote
yourself.  (Each ForeignPtr can have a different freeing function if
you want.)  (ForeignPtrs are often called Weak Pointers in other languages)

Since C doesn't have automatic GC, StablePtrs are explicitly allocated and
deallocated.  As long as a stable ptr exists, the Haskell GC knows that
the object is in use and doesn't deallocate it.  Once the stable ptr is
free'd the GC is free to deallocate it (assuming it's not needed for
any other reason).


ForeignPtrs seem to work ok for abundant resources like memory.  
When using scarce resources, code like the following is quite common:

    if (i>=NUM_HANDLES) {                       /* If at first we don't    */
        garbageCollect();                       /* succeed, garbage collect*/
        for (i=0; i<NUM_HANDLES && nonNull(handles[i].hcell); ++i)
            ;                                   /* and try again ...       */
    }
    if (i>=NUM_HANDLES) {                       /* ... before we give up   */
        ERRMSG(0) "Too many handles open; cannot open \"%s\"", s
        EEND;
    }

(This code is part of Hugs.  It doesn't actually involve ForeignPtrs - 
 Mark Jones had used a ForeignPtr-like mechanism to implement file handles
 long before I added ForeignPtrs.)


-- 
Alastair Reid              Yale Haskell Project Hacker
[EMAIL PROTECTED]  http://WWW.CS.Yale.EDU/homes/reid-alastair/




Reply via email to