chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] "Dynamically Loading" non-entry-point code


From: Daniel B. Faken
Subject: Re: [Chicken-users] "Dynamically Loading" non-entry-point code
Date: Tue, 22 Jun 2004 16:32:15 -0400 (EDT)

On Tue, 22 Jun 2004, Felix Winkelmann wrote:
> Daniel B. Faken wrote:
> 
> > On Tue, 22 Jun 2004, felix wrote:
> > 
> >>Daniel B. Faken wrote:
> >>
> >>>I need to call it from C (because I want the library to basically load 
> >>>some of its own bindings), so I defined this in my "scmif" interface
> >>>layer (see below)
> >>>
> >>>Do you see any problem with this?  (I wasn't too sure what you meant by 
> >>>"it gets complicated")   Will this work with arbitrarily nested layers of 
> >>>callback?

<snip>

> >   Sorry, I should have mentioned that; it *seems* to work just peachy.  I 
> > have happily been able to simplify three separate packages this way.  My 
> > question was more regarding if there was some theoretical problem..
> > I.e. what exactly would calling it 'just' from scheme (as per your 
> > suggestion) do differently from my C-calling-Scheme + 
> > one-layer-of-indirection
> > code?
> 
> By what I can infer from your example, it should work. The important
> issue is to make sure no calls from Scheme to C into Scheme happen, that might
> trigger a garbage collection without saving some context data (like the
> continuation of the outermost Scheme context).
> The other important issue is that, for GC to work, a "restart" trampoline
> has to be established, so that once a minor GC has been run, something
> is there that can be longjmp'd to.
> And yet another important issue is that a minor GC may not simply remove
> live C stack frames.

Are you speaking in general, or are these GC concerns only for this 
library-initialization business?

I should have added a __callback in front of the _scmif_run_toplevel 
function (eqv. of your run_foo_unit) -- does this address the concerns
you speak of?

I guess I should Read The Fine Source; I was just hoping it would behave 
similarly to the other FFI mechanisms in Chicken..

> Depending on your definition of scmif_eval_stringf, your example looks ok
> to me.

I currently have it using the "safety layer" (see below) to call a
little, protected read-eval (in Scheme).

> >   FWIW, I've also used this kind of indirection technique to add scheme
> > bindings to C functions at run-time and to add a safety layer so functions 
> > can be called whether the Chicken toplevel is active or not 
> 
> Interesting. Can you give more information about how you setup the
> safety layer?

Its very similar to the way I was calling the toplevel function:

#>!
__callback static int _scmif_do_C_cb(void *fn_ptr, void *data)
{
  int (*fn)(void *) = fn_ptr;
  assert(fn_ptr);
  return fn(data);
}
<#

(define-embedded "static"
  (scmif_ep_safe_callback (c-pointer fn) (c-pointer data)) int
  (_scmif_do_C_cb fn data))

#>
int scmif_safe_callback(int (*fn)(void *), void *data)
{
  assert(fn);

  if(CHICKEN_is_running())
    return fn(data);
  else
    return scmif_ep_safe_callback((void *)fn, data);
}
<#

..the idea is that if the user has a Scheme function thats been exported 
to C, s/he defines a wrapper for it:
static int call_my_scm_fn(void *data)
{
  mydata *d = (mydata *)data;
  special_scheme_function(d->name, d->rank, d->turkey);
}

..and then calls
  scmif_safe_callback(call_my_scm_fn, foo);

..and so the function is always called from within scheme (i.e. within a 
toplevel context).

Of course, I wish I didn't have to write a wrapper function - but this 
allows fairly general, efficient behaviour without more work on the FFI's 
part (like defining things such as a variant of scmif_safe_callback for
each possible C function signature, or generating some wrapper code 
around each exported C function).

Thoughts?

best,
Daniel






reply via email to

[Prev in Thread] Current Thread [Next in Thread]