Fusion:Call
From DirectFBWiki
A fusion call is a way of sharing a function so that may be executed from another process. That is, it’s a remote procedure call (RPC).
The fusion call API only provides a mechanism for executing the call. You’ll have to put a FusionCall structure in shared memory and publish a pointer to it (or to a containing structure) in an arena so that other fusionees can call it – there’s no binding available beyond what’s offered through the arena abstraction.
You export a function that you want to make available to other fusionees in your world by passing a pointer to it to fusion_call_init(), which will fill in your FusionCall structure. You can also specify a context (ctx), which is just a pointer that will be passed to your function verbatim no matter which fusionee executes it.
Every shared call has the same prototype:
int fbdev_ioctl_call_handler(int caller, int call_arg, void *call_ptr, void *ctx)
- The caller is the fusion id of the calling fusionee.
- The arg and ptr parameters are generic values passed straight through from the caller to be used however you want to use them.
- The context provided to fusion_call_init() is passed back in the ctx parameter.
The return value of your called function is passed back to the caller to use. However, you can also pass back a return value to the caller before you’re done executing by using the fusion_call_return() function. If you do that, when your function really does exit its return value will be tossed away.
You call a shared function by passing a pointer to the relevant FusionCall structure to fusion_call_execute(). The return value of this function tells you whether there was an error making the remote call. The result of the remote call is passed back to you through the ret_val parameter.
When you’re done with the shared function, you need to cleanup with a call to fusion_call_destroy(). If you try to execute a call after it is destroyed you’ll just get an error back.
The context pointer doesn’t necessarily have to reference shared memory because when your function is finally executed, it will (usually) be within fusion’s message-loop running in a thread in your process. However, since you’re using fusion, chances are that your function will end up doing stuff that requires shared memory anyway.
Simultaneous executions from other fusionees will be queued up to execute one-at-a-time in the target fusionee’s message-loop thread. If you execute one of your own calls, however, the message-loop will be bypassed and the function will actually be executed from the same thread that called fusion_call_execute(). In that case, if the function should use fusion_call_return() it will have no effect, and the actual return value of the function will be set the the ret_val parameter when the call finally finishes.
Multi-app: In the single-app configuration, the implementation is simpler, but the behaviour is the same as always executing your own calls in the multi-app configuration (i.e. no read-loop thread, and no early returns).
