[gambit-list] Anyone else working in a schemey wrapper for c structs/unions/types?

Estevo euccastro at gmail.com
Wed Dec 25 17:21:52 EST 2013


> I have never been aware of anything like that. Can you provide a proof of
> concept example code that shows how weak references to a FFI object would
> be inconsistent?
>

The problem is not that they're inconsistent.  The problem is they can't
really tell you when an object that is depended upon is safe to free.  I
gave an example of that in this thread:

https://mercure.iro.umontreal.ca/pipermail/gambit-list/2013-December/007335.html


> You can implement this kind of behavior in Gambit (i.e. B is referenced to
> by or actually contained in A so you want freeing of B to be conditioned to
> the freeing of A happening before) yourself, for instance by
>
>  1) ensuring you have a reference to B in some vector or alike, one that
> guaranteedly will stick around until A is freed. Also, you could
>

Once user code gets hold of A, pure Scheme code can't really know when it's
OK to let go of that vector.  It's the same problem.  Of course you can
keep a reference forever, but you don't want to hold on to unneeded memory
either.


>  2) use the "refcount" facility that Gambit exports to the C world, to
> keep B's refcount +1 as long as A refers to it, and then have A's release
> procedure -1 its refcount on invocation.
>

Something like this might work, thanks!  I had given up on foreign release
functions because they are C functions that can only be set (or so I
thought) per foreign object type (the ones you create in c-define-type) and
not per instance, they can't be closures, and they won't get any arguments
but the foreign's pointer to C data.  Also, you can only set one, so if you
use it for this you can't use it for anything else.

But these restrictions need not be showstoppers.  A scheme that might work:
 - on initalization, create an ___alloc_rc'ed table[1] and assign a global
C pointer to it
 - whenever you create a dependent foreign pointer F, store in the table a
reference to its dependent object D, keyed by the address of the F's C
pointer, and
 - set a release function for F that will clear that entry in the table.

This should work because unlike wills, release functions will only be
called when their object is not reachable from Scheme code (barring FFI
black magic).

What practical task are you solving?
>

I'm making a library that lets you define C struct/union/type constructors,
accessors and mutators using a syntax analogous to that of
define-structure.  Here's how you define C structure wrappers:

https://github.com/euccastro/gambit-SDL2/blob/master/c-test-ffi.scm

and here's how you use them

https://github.com/euccastro/gambit-SDL2/blob/master/test-ffi.scm

Here's a non-test example:

https://github.com/euccastro/gambit-SDL2/blob/master/sdl.scm

This is from a very old version and it shows that I didn't know what I was
doing :), but it does showcase the user interface.  The point is that using
C structures from Gambit code should be effortless, straightforward, safe,
and fit well both with Scheme and with FFI code that doesn't follow your
approach.

I'll give the scheme above a go and let you know how it goes.  I think the
solution involving my patch[2] should yield better performance because it
doesn't involve any table following and, not requiring the use of release
functions, allows you to set the last parameter of c-define-type to false.
But maybe this won't matter in practice.

Thanks again!

[1] Globals won't do because the garbage collector doesn't scan those.
Movable objects won't do because you can't reliably keep a C pointer to
them.
[2] Which, by the way, I've simplified down to a 5-line change.  See
https://github.com/feeley/gambit/pull/61
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20131225/3b473b19/attachment.htm>


More information about the Gambit-list mailing list