[erlang-questions] idea: Erlang FFI: callbacks and memory management

Scott Lystig Fritchie <>
Thu Dec 13 19:46:26 CET 2007


>>>>> "rv" == Robert Virding <> writes:

rv> If you have a callback how do you intend to get data in and out of
rv> them?  Callbacks can't live without shared data. In which process
rv> are they to be evaluated? Everything in Erlang exists within a
rv> process.

rv> No, the only workable Erlang way is to replace them with messages.

My memory is quite fuzzy by now, but I think that Tony Rogvall
(perhaps?) had managed to do something like what Alceste is asking
for.  I forget what driver he'd done, perhaps a GUI-related something,
but the message passing was clever.

On the Erlang side of the driver, if you had this (not actually
tested!):

    Port ! {Pid, {command, DataForCFuncX}},
    receive
	{Port, {data, [?FuncXReply|FuncXDetail]}} ->
	    do_stuff_with_reply(FuncXDetail)
    end

... is substituted with this (not parameterized to deal with multiple
driver functions or multiple callback functions) (not tested!):

    Port ! {Pid, {command, DataForCFuncX}},
    wait_for_reply(Port, Pid).

wait_for_reply(Port, Pid) ->
    receive
	{Port, {data, [?FuncXReply|FuncXDetail]}} ->
	    do_stuff_with_reply(FuncXDetail)
	{Port, {data, [?CallbackRequest|CallbackDetail]}} ->
	    CallbackResult = callback_func(CallbackDetail),
	    Port ! {Pid, {command, [?CallbackResponse, CallbackResult]}},
	    wait_for_reply(Port, Pid)
    end

The Erlang side could deal with a driver that asked for more than 1
callback call before returning its final result.

This assumes that the driver call is synchronous, from the Erlang
caller's point of view -- the driver then uses the same Erlang process
as the context/environment/thingie for executing the callback.  If the
Erlang side is asynchronous, then this scheme doesn't work as well.  :-)

-Scott



More information about the erlang-questions mailing list