Modules
In the lib-common, Modules can be defined and work in a similar way as kernel modules, allowing us to load blocks of functionalities with little effort.
Modules are declared using MODULE_BEGIN(module_name)
/MODULE_END()
macros.
This creates a function with
__attribute__(constructor)
The body of this function is called before main(), as long as the module is linked in your executable.
It builds the dependencies between modules, using:
-
MODULE_DEPENDS_ON(x)
(load the module "x" before this one, a classic dependency) -
MODULE_NEEDED_BY(x)
(load this module before loading module "x", a reversed dependency).
When loading a module, 2 things happen:
-
all the automatic dependencies (
MODULE_DEPENDS_ON
) not loaded yet are loaded (this is recursive, so their dependencies are loaded first, and their<dep>_initialize()
method is called before too). -
then the
<module_name>_initialize()
method is called.
When unloading a module :
* all the dependencies that are not needed anymore are unloaded.
* the <module_name>_shutdown()
method is called.
MODULE_PROVIDE(module_x, arg)
ensures that the argument is passed to
module_x_initialize(). Warnings will be issued if a module is provided an
argument more than once.
Sometimes, you need conditional dependency. This is achieved using
MODULE_REQUIRE(x), which does an immediate load. This is usually done in
<module>_initialize
, but could be done anywhere. A manually loaded module
must be manually unloaded, using MODULE_RELEASE(x)
.