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. <color gray>This class also provides a basic mechanism for controling static initialization when TerraLib is built as an static library. (TODO)</color>

Design

In the following class diagram we present the TerraLib singleton and the internal structure Module.

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).
  • <color gray>the list of required modules (dependency list). (TODO)</color>

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<Module>
{
  friend class te::common::Singleton<Module>;
 
  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.

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 Module Utils.

From Theory to Practice

The code snippet below shows how to perform the TerraLib Platform initialization and cleanup:

#include <terralib/common/TerraLib.h>
 
...
 
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 Module Utils section.

References


QR Code
QR Code wiki:designimplementation:common:modulemanagement (generated for current page)