I created a Legato component which uses API for voicecall service and additionaly I created an application which uses the component. Both INIT functions are queued in the event queue what means that with “app start myApp” the COMPONENT_INIT callback functions are called. My question now is, how does the application/component get information about an “app stop myApp”. If there is some cleanup work to do e.g. release of resource or memory, then the application/component needs to now that it’s stopped.
I was looking for a COMPONENT_EXIT or whatever, even had a look to the Event Loop API, but couldn’t find such information.
How to handle the stop condition in the application or component?
Currently there is not a way to do this. Right now, we make use of the fact that the OS will automatically reclaim your app’s OS layer resources. Also, all Legato IPC servers are notified on client disconnect so that they can handle any per-client clean up they require. For instance if a client dies in the middle of a configTree transaction, the config service can automatically cancel that transaction and allow other processes to continue.
This actually ends up covering a large number of use cases. However, if this doesn’t cover what you are trying to do, please let us know. Perhaps there’s a clean way we can fold this into the framework.
I like the idea of a COMPONENT_EXIT, but that would force the addition of that function in every component, even if they didn’t need it. While registering a function for the shutdown could be used when needed, but at the expense of complexity.
There is also a way to do this with straight POSIX calls.
You can register a function with atexit() that will be called when your process exits via either returning from main or through a call to exit(). However, the supervisor sends a SIGTERM to shutdown apps, so you will also have to register a term signal handler.
From the term signal handler all you should have to do is call exit and your atexit handler will be called. Checkout le_signals.h for a Legato API for handling signal registration. http://www.legato.io/legato-docs/14_10/c_signals.html You also need to block the signal manually, using pthread_sigmask, (safe for multi-threaded and single-treaded apps.)
The pitfall here are that signal handlers are a global resource, so if another component comes along and registers a handler for your signal your code may never get called.
Some background info related to this, in case anyone is interested:
In early days of the project, we did talk about having a COMPONENT_EXIT or COMPONENT_DESTRUCTOR or something like that. The reasons we decided against it were:
applications run in sandboxes, and the Supervisor will clean up anything in the sandbox temporary file system when the app goes down;
as Kelly said, much of the cleanup is handled for you, so most components wouldn’t need any cleanup handler;
applications should really be designed to survive a hard interruption, such as a sudden, unexpected power failure or reset.
For this last point, we use “the rock-paper-scissors algorithm” with our persistent data.