[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Chicken-users] newbie: foreign pointers that depend on Scheme objects
From: |
Alejandro Forero Cuervo |
Subject: |
[Chicken-users] newbie: foreign pointers that depend on Scheme objects |
Date: |
Mon, 15 Dec 2008 22:34:15 +0100 |
User-agent: |
Mutt/1.5.13 (2006-08-11) |
I have a question about what the best way to achieve something with
Chicken's FFI might be. This is based on problems I'm having with the
svn-client egg (so the actual code is more complex, this is just a
simplification) for some modifications that I'm making to implement
some new functionality in Svnwiki.
Lets say I have the following C structure:
struct closure {
void *data;
void *proc(void *data);
};
Lets say I have a function that builds one such structure and returns
it:
void create_closure(void *data, void *proc (void *));
(Please ignore syntax errors in the above C code; the intention should
be clear.)
Now, if I want to make create_closure callable from Scheme, I'm doing
the following:
(define-record c-closure ptr)
(define (make-c-closure-with-finalizer x)
(set-finalizer! x (foreign-lambda void "free_closure" (pointer "closure")))
(make-c-closure x))
(define-foreign-type
c-closure-type
(pointer "closure")
c-closure-ptr
make-c-closure-with-finalizer)
(define-external (call_the_proc (scheme-object proc)) scheme-object
(proc))
(define create-closure
(foreign-lambda* c-closure ((scheme-object proc))
"return(create_closure(proc, call_the_proc));"))
This, evidently, has problems. If the programmer does
(create-closure (lambda () (foobar))) ,
the dependency of the resulting c-closure on the parameter passed to
create-closure is not registered anywhere. So it may get GCed. And,
furthermore, IIRC, it may get moved to a different address so the C
pointer data will be rendered invalid.
So what's the best way to solve this?
One idea I had was to do the following (plus tweaks to call_the_proc
to de-ref the GC root):
(define create-closure
(let ((obj ((foreign-lambda* c-closure ((scheme-object proc))
#<<EOF
void *root = CHICKEN_new_gc_root();
CHICKEN_gc_root_set(root, proc);
return(create_closure(root, call_the_proc));
EOF
) proc)))
(set-finalizer! (c-closure-ptr obj)
(foreign-lambda* void ((c-closure obj))
"CHICKEN_delete_gc_root(obj->data);"))
obj))
I actually don't think this would work: there could be loops if the
Scheme-level closure depends on an object that is eventually modified
to depend on the C-level closure object (the object returned by
create-closure) so even if there are no other references to these
objects, they won't be GCed.
So how should I solve this problem?
Thanks.
Alejo.
http://azul.freaks-unidos.net/
- [Chicken-users] newbie: foreign pointers that depend on Scheme objects,
Alejandro Forero Cuervo <=
- [Chicken-users] newbie: questions about set-finalizer!, Alejandro Forero Cuervo, 2008/12/15
- Re: [Chicken-users] newbie: questions about set-finalizer!, felix winkelmann, 2008/12/16
- Re: [Chicken-users] newbie: questions about set-finalizer!, felix winkelmann, 2008/12/17
- Re: [Chicken-users] newbie: questions about set-finalizer!, Alejandro Forero Cuervo, 2008/12/20
- Re: [Chicken-users] newbie: questions about set-finalizer!, felix winkelmann, 2008/12/21
- Re: [Chicken-users] newbie: questions about set-finalizer!, felix winkelmann, 2008/12/22
- Re: [Chicken-users] newbie: questions about set-finalizer!, felix winkelmann, 2008/12/22
Re: [Chicken-users] newbie: foreign pointers that depend on Scheme objects, felix winkelmann, 2008/12/18