====== TerraLib Common Runtime → Module Management ====== Sometimes a module needs to initialize some resource like buffers, static data or threads. There is a singleton called **TerraLib** designed to help controlling the startup and cleanup of TerraLib Platform and its resources at runtime. This is a special class that can be used by TerraLib modules to register special functions that must be called when the platform or the modules are initialized or finalized. This class also provides a basic mechanism for controling static initialization when TerraLib is built as an static library. (**TODO**) ===== Design ===== In the following class diagram we present the **TerraLib** singleton and the internal structure **Module**. {{:wiki:designimplementation:common:terralib_class.png|TerraLib class}} As one can see, the singleton keeps the following information about each module: * the module name: an internal value used to identify the module in the system. Must be a unique value. We suggest to use some value that indicates the namespace hierarchy of the module. For example: //te.common// (for the common module) or //te.gm// (for the geometry module). * a pointer to an startup routine responsible for performing the module initialization (may be a null pointer). * a pointer to a cleanup routine responsible for performing the module finalization (may be a null pointer). * the list of required modules (dependency list). (**TODO**) The ''initialize'' method will perform the startup of all registered modules. If there is no modules to be initialized this method has no effect. The startup function registered for each module will be invoked in the direct order of registering: the first module to be registered will be the first to be initialized. Notice that this method is not thread-safe and may throw an exception. If an exception is raised we recommend you to quit the program; don't try to resume it because you can have intermittent errors. The ''finalize'' method performs the cleanup of all registered modules. The shutdown function of each registered module will be invoked in an opposite order of registering: the last module to be registered will be the first module to be finalized. As the ''initialize'' method it is not thread-safe and if it throws an exception we recommend you to quit the program; don't try to resume it because, as in initialize method, you can have intermittent errors. When a module needs a special initialization or finalization it can register its information in this singleton through the ''add'' method. We suggest the following strategy in order to register a module called //MyModule//: Create a header file like //MyModule.h//: // TerraLib #include "Singleton.h" class Module : public te::common::Singleton { friend class te::common::Singleton; protected: Module(); ~Module(); private: static void initialize(); static void finalize(); private: static const Module& sm_module; }; Then create a source file like //MyModule.cpp//: #include "Module.h" #include "TerraLib.h" // The magic auto-registration! const te::common::Module& sm_module = te::common::Module::getInstance(); te::common::Module::Module() { TerraLib::Module m = { "my.module.name", Module::initialize, Module::finalize }; // register the module TerraLib::getInstance().add(m); } te::common::Module::~Module() { // unregister the module before it is unloaded TerraLib::getInstance().remove("my.module.name"); } // this static method may be invoked when platform is initialized void te::common::Module::initialize() { } // this static method may be invoked when platform is finalized void te::common::Module::finalize() { } ===== Module ===== As discussed above every module may have a class that helps registering the initialization/finalization routines. The common module has a singleton called //Module// that defines an entry in the Platform for the TerraLib Common Runtime module. {{:wiki:designimplementation:common:class_module.png|Module class}} This class is responsible for: * registering the initialization and cleanup routines for the Common Runtime module. * start the logger configuration if TerraLib is configured to have it initialized automatically. * registering the Common Runtime multilingual support. * ordering the singletons creation. When creating a module you will find useful to look this class design and also the set of routines available in [[:wiki:designimplementation:common:utils#moduleutils|Module Utils]]. ===== From Theory to Practice ===== The code snippet below shows how to perform the TerraLib Platform initialization and cleanup: #include ... int main(char** argv, int argc) { ... // other initializations goes here! TerraLib::getInstance().initialize(); ... // now you can start using TerraLib! TerraLib::getInstance().finalize(); // call this when you have finished using TerraLib return EXIT_SUCCESS; } Notice the calling to the finalize function at the end of the example program, it is necessary in order to close/release any pending resource initialized by the modules. ===== Final Remarks ===== * The above mechanism provides two level of initialization/finalization: * when the statics are being initialized the Module class (a singleton) can be useful for controling which singleton is created first. The first singleton having its constructor finished will be the last singleton to be claimed by the system. * after all the statics have been initialized the main routine is called. * Another intermediary strategy that can be used is to have an automatic initialization after the statics have been created and before the main routine starts executing. This is covered in the [[:wiki:designimplementation:common:utils#moduleutils|Module Utils section]]. ===== References =====