Re: GC safety and return values Tom Lord 23 Dec 2003 23:04 UTC


    > From: Jim Blandy <xxxxxx@redhat.com>

    > The points I made in the very first post to this SRFI's
    > discussion list still apply, though --- GCPRO cannot be made to
    > work in multi-threaded contexts.

I think that that's overstated.

SRFI-50 does need some work (perhaps nothing more than more precise
specification) to support threads, and does need some work on the GC
interface, but a GCPRO-technique can still work and is arguably
preferable to a JNI-style reference-object technique.

You expressed concern about the GC relocating objects addressed by
pointers returned from SCHEME_EXTRACT_VALUE_POINTER and
SCHEME_EXTRACT_STRING.  These issues are solvable by any of a variety
of means, including:

1) add a notion of "critical sections" during which GC is excluded

   Those pointers can remain valid within an (explicitly declared)
   critical section and not otherwise.  Other functions in the FFI
   must then be labled with "use only in a critical section", "never
   use in a critical section", and "use anywhere".

2) Make those particular pointer values immobile (by GC, at least).

   Probably a non-starter because it does impose a restriction on
   implementation techniques.   I mention it because I happen to think
   it's not an unreasonable restriction (but I doubt that a consensus
   would be easy to form around that).

3) Change the Semantics

   Instead of EXTRACT we might want ALLOCATE_COPY_OF.

4) Promise only that the pointers returned are for read-only purposes.

   The EXTRACT routines can allocate one or more stable copies of the
   object in question between GCs, freeing those on GCs.

Of those, I recommend (1) for the simple reason that if, for example,
the FFI were extended with finalizers for boxed values otherwise
managed by C code, the lack of support for GC-excluding critical
sections will be sorely felt, even in single-threaded systems.
(Basically, programmers need to be able to say not only "I'm holding
the address of some Scheme object's representation" but also "Between
HERE and THERE the state of the heap is inconsistent as far as the GC
is concerned.")

Meanwhile, I don't see how JNI-style refs actually solve this problem
anyway.  So, fine: I have a "reference object" to a Scheme string.  I
want to operate on a "char *" pointing to its data -- not a ref to
that "char *" -- because I want to pass it to some libc function.  The
mere introduction of the reference object doesn't preclude the GC from
invalidating my "char *".

-t