[erlang-questions] RFC: Erlang FFI
Alceste Scalas
alceste@REDACTED
Fri Aug 10 12:30:49 CEST 2007
Scott Lystig Fritchie <fritchie@REDACTED> wrote:
> Most of the Erlang<->C/C++ efforts have been SWIG-like efforts to
> present as smooth an interface to the non-C side as possible. In
> Erlang, IMHO(*), such integration has been even more important. At
> least half of Erlang's advantage is its ability to survive faults(*),
> and creating arbitrary interfaces into unknown shared libraries is a
> good way to invalidate much/all of those survival mechanisms.
> [...]
> Such an interface to libffi makes it possible to create Erlang
> interfaces to *any* shared library, without recompiling or relinking
> or other steps. To create the same "smooth" interface, the glue ends
> up being on the Erlang side of the divide. That philosophy is
> opposite from most FFI efforts in the Erlang world.
>
> There are 2 main FFI camps, it seems to me(*):
>
> 1. I don't care about fault tolerance, I *must* access to function
> F in library L, and to hell with the consequences of buggy
> code.
>
> 2. I really care about fault tolerance ... because if I didn't, I
> wouldn't bother with Erlang at all.
I would like to point out something that I forgot to emphasize in my
previous email: the expected uses of the FFI BIFs I'm proposing.
Just like ddll:load/3, erlang:port_control/3 and friends, the FFI BIFs
(ffi:call/3, ddll:load_library/3, ffi:call/2, ffi:ecall/3) are *not*
intended to be used by "standard" Erlang developers. They are
actually targeted at two kinds of, let's say, Erlang power developers:
1. library bindings developers;
2. developers that need to interface Erlang code with
C/Fortran/Assembly/whatever (e.g. for performance reasons, thus
making even the call speed a relevant factor).
This is directly related to your fault-tolerance and stability
worries. The FFI BIFs could be used to crash the Erlang VM more or
less like a linked-in driver could [1]. But unaware developers that
just want to use libfoo from Erlang are usually *not* directly exposed
to the gore details of Erlang drivers: they don't see
erlang:port_control/3 (or ffi:call/3), but a documented Erlang libfoo
API that takes care of validating the parameters and performing the
underlying machinery. If a developer decides to bypass this API layer
and access libfoo by fiddling with erlang:port_control/3 (or
ffi:call/3), then he/she is definitely on his/her own.
The main difference between linked-in drivers and FFI BIFs, IMHO, is
that ffi:call/3 and friends make it a lot easier to develop library
bindings and to interface external code to Erlang, both for
quick'n'dirty hacks and well-refined products. The FFI approach is
also more powerful, expecially with the proposed ffi:ecall/3
BIF [2].
I agree when you write that, when safety and fault-tolerance are
fundamental and "untrusted" code could not be allowed, the ideal
solution would be to run the untrusted FFI code in a separate process.
But it may require quite some work. From this point of view, I agree
with Denis: instead of developing more-or-less transparent pipe driver
with complicated serialization (as pointed out by Vlad), one may run
one or more Erlang nodes with the unsafe stuff, and issue remote calls
through a simplified API layer. This could be the cheaper and
possibly more flexible way to obtain both FFI and greater
fault-tolerance (at the price of speed, of course). And this approach
could even be used with "untrusted" linked-in drivers.
Regards,
alceste
Notes:
[1] Well, one may program an erlang:port_control/3 C callback that
reacts gracefully to every possible kind of garbage being received
as binary data. But the same defensive programming could be done
for C functions expected to be called through ffi:call/3. Being
able to call arbitrary C functions through FFI BIFs doesn't
prevent a library binding developer to create and document a set
of "safe" C functions that could be called from Erlang, with the
warning that other calls may have unexpected consequences.
[2] Let's see an "extreme" scenario: something like ffi:ecall/3
with some glue code based on libffi closures would allow (at least
in theory) to pass an Erlang fun() to the C side to be used as a
callback, even from code that is completely Erlang-unaware (as
an example: write a differential equation in Erlang and let the
GNU Scientific Library integrate it). I didn't find a way (yet)
to apply/3 an Erlang fun() from C code, but I didn't do much
investigation in the Erlang VM internals. The possibility to
call C-from-Erlang and Erlang-from-C, however, would increase
the Erlang language interoperability to the levels of Python,
Java, etc.
--
Alceste Scalas <alceste@REDACTED>
CRS4 - http://www.crs4.it/
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
More information about the erlang-questions
mailing list