[plt-scheme] Proposal: Async FFI

From: Eli Barzilay (eli at barzilay.org)
Date: Sat Jul 7 20:43:53 EDT 2007

On Jul  8, Hans Oesterholt-Dijkema wrote:
> Dear All,
> In my sqld-psql-c driver (see PLaneT) I've used an asynchronous mechanism
> to call pqexec (a synchronous function call for PostgreSQL). I've done this
> to enable scheme threads to run, while processing SQL queries.
> I'd like to add such a mechanism to the FFI. Maybe through PLaneT, but
> eventually I'd like this to be added to the FFI code. This will help greatly
> for using certain libraries through the FFI, where functions can block for
> a long time, e.g. DB2CLI, MySQL. But other C libraries, e.g. for image
> processing can also be thought of.
> My idea is to provide a set of basic C functions, like:
> int f(int)
> void f(int)
> int f(string)
> ...
> The C code for these functions can be generated. These functions do
> the trick that can be reviewed in the sqld-psql-c PLaneT package, in
> a generic way.
> The FFI could be extended with get-ffi-obj/async. To provide calls
> of these asynchronous functions. Of course this variant will have a
> lot of restrictions, but this basic support would be quite good
> already.

A `get-ffi-obj/async' doesn't sound good.  I think that a better way
to have async calls is some new primitive like

  (ffi-call/async ptr in-types out-type)

that is similar to `ffi-call' (which is the primitive that the
foreign.ss library builds on) -- the result is a Scheme procedure that
expects one more argument which is a callback function.  For example,
with `ffi-call' you do something like this (this is a rough
approximation to how "foreign.ss" does things):

  (define cfun (ffi-call some-fun-pointer (list _int _bool) _int))
  (printf "cfun returned ~s\n" (cfun 15 #f))

and with `ffi-call/async':

  (define cfun* (ffi-call/async some-fun-pointer (list _int _bool) _int))
  (cfun (lambda (r) (printf "cfun returned ~s\n" r))
        15 #f)

But there is one major problem with all this...  MzScheme assumes that
all calls to C are atomic, so it will be easy to make things break in
unexpected ways.  (The simplest would be to have the asynchroneous
call use a Scheme callback.)

(This is on top of the usual problems like making whatever code yo
write work on everything, including Windows, Solaris, OSX, *BSD, etc.)

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!

Posted on the users mailing list.