Page MenuHomePhabricator

Avoid entanglement of global static objects and singletons
Closed, ResolvedPublic

Description

MITK has been bitten by the static initialization and destruction order problem several times.

In a complex toolkit like MITK, consisting of multiple libraries and plug-ins, the management of static objects, especially their dependencies on each other during construction and destruction is unfeasible.

T4733 for example has been around for nearly a year due to this problem and some strategies have been discussed. Looking at other large (and much larger) frameworks and applications, this problem is often overcome by the use of a central registry managing the life-cycle and dependencies of objects added at runtime.

I suggest to use a service oriented approach like in CTK (based on OSGi) but without the module life-cycle layer. This would give us a very powerful and dynamic "service registry", enabling the design of SOA in MITK. Existing singletons would be converted into services and registered and library loading and unregistered at library unloading. Services will have no hard dependencies on each other but would use the registry for a dynamic look-up.

A prototype implementation looks like this:

//****** BEGIN ******
struct MyInterface
{

virtual void DoSomething() = 0;

};

MITK_DECLARE_SERVICE_INTERFACE(MyInterface, "org.mitk.MyInterface")

class MyImplementation : public itk::LightObject, public MyInterface
{
public:

void DoSomething() { ... }

};

In some cpp file of the library declaring the MyImplementation class:

static MyImplementation* myImpl = 0;

MITK_MODULE_START(context)
{

myImpl = new MyImplementation(...);
context->RegisterService<MyInterface>(myImpl);

}

MITK_MODULE_STOP(context)
{

// the service is unregistered automatically on library unloading

// controlled deletion of the service object
delete myImpl;

}
//******* END *******

Each module can register and unregister additional services arbitrarly
at runtime by doing

GetModuleContext()->RegisterSerivce(...)

For this to work I have done the following changes:

  1. Added a OSGi Service Layer implementation to MITK, based on the STL and ITK.
    • Where should those files go? Core/Code/Controllers? They have names like mitkServiceFilter.h, mitkServiceProperties.h, mitkModuleContext.h, mitkModule.h, mitkModuleRegistry.h, etc.
    • Where should the associated utility files go? For example mitkAtomicInt.h, mitkStaticInit.h, mitkLDAPExpr.h, mitkSharedData, etc.
  1. Modified the MITK_MACRO_CREATE_MODULE CMake macro to create a .cpp file for each module containing meta-information and a static initializer class.
  1. Added some utitlity macros to mitkCommon.h

Event Timeline

Resetting all bugs without active assignee flag to "CONFIRMED". Change status to IN_PROGRESS if you are working on it.

A fully tested implementation of the discussed concepts is now available.

I like to call it "MITK Micro Services", and it is available in the topic branch "bug-8753-mitk-micro-services". Please review the changes and add your remarks.

Here is an overview of the additions contained in the branch:

  1. Minor tweaks regarding include paths and doxygen (first three commits)
  1. Introduced code snippet support (is not related to the Micro Services, but used in the documentation of it)
  1. Added experimental support for C++0x features (for now only hash containers). ITK provided hash containers (the SGI implementation) but I had to modify it to be able to work with certain STL iterator concepts. If C++0x support is enabled, std::unordered_map is used. In VC10, C++0x support is enabled by default.
  1. The Micro Services framework itself, with documentation and unit tests.
  1. Qt classes and a BlueBerry View for displaying the currently loaded MITK modules

[e7cde8]: Merge branch 'bug-8753-mitk-micro-services-2'

  • bug-8753-mitk-micro-s

Merged commits:

2011-08-30 18:56:44 Sascha Zelzer [651de9]
Added a "Modules" view displaying known modules.


2011-08-30 18:56:01 Sascha Zelzer [f2f50d]
Cleaned up the about dialog and added a button to show known MITK modules.


2011-08-30 18:55:16 Sascha Zelzer [fe80cb]
Added a QDialog subclass for displaying MITK Modules.


2011-08-30 18:53:45 Sascha Zelzer [fecad2]
Added a Qt table model for MITK Modules.


2011-08-30 18:51:56 Sascha Zelzer [484ef0]
Implementation of the MITK Micro Services.


2011-08-30 18:45:56 Sascha Zelzer [490dfd]
Added experimental support C++0x hash containers.


2011-08-30 18:43:47 Sascha Zelzer [28ecd1]
Added support for code snippets.

With doxygen 1.7.5, a new command "\snippet" was introduced. The MITK
build system now supports easy creation of such snippets as source code
which is regularly compiled and which can be embedded in doxygen
documentation blocks.


2011-08-30 18:37:32 Sascha Zelzer [5a3a83]
Added doxygen "Core Classes" group and tweaked public doc options.


2011-08-30 18:32:56 Sascha Zelzer [5f2716]
Refactored mitk::Message classes

  • Use const Execute and operator== methods
  • Use a base class for Message to reuse code
  • Implement correct copy constructor and assignment operator

2011-08-30 18:17:05 Sascha Zelzer [edd1c9]
Fix MITK variables containing include and linker directories.

When using MITK_INCLUDE_DIRS and MITK_LINK_DIRECTORIES outside the
module system, GDCM and mbilog directories were missing.

[46e697]: Merge branch 'bug-8753-mitk-micro-services-2'

  • bug-8753-mitk-micro-s

Merged commits:

2011-09-05 03:46:54 Sascha Zelzer [14a747]
COMP: Added missing macro argument

[5d6df4]: Merge branch 'bug-8753-mitk-micro-services-2'

  • bug-8753-mitk-micro-s

Merged commits:

2011-09-05 11:43:10 Sascha Zelzer [fe2f2e]
COMP: Use - instead of / in Visual Studio project names


2011-09-05 11:42:49 Sascha Zelzer [a74532]
COMP: Added missing Windows includes

[b515f5]: Merge branch 'bug-8753-mitk-micro-services-2'

  • bug-8753-mitk-micro-s

Merged commits:

2011-09-05 14:42:41 Sascha Zelzer [5cf593]
COMP: MITK modules (which do not pass NO_INIT) need a "Mitk" dependency.


2011-09-05 14:42:07 Sascha Zelzer [ed5375]
COMP: Use correct header files.


2011-09-05 14:41:02 Sascha Zelzer [508fb4]
COMP: Use MITK_LOCAL defines.

[6510a9]: Merge branch 'bug-8753-mitk-micro-services-2'

  • bug-8753-mitk-micro-s

Merged commits:

2011-09-05 16:08:12 Sascha Zelzer [401209]
COMP: Added more missing includes.


2011-09-05 16:07:58 Sascha Zelzer [2b0de3]
COMP: Moved MITK_EXPORT_MODULE_ACTIVATOR to mitkModuleActivator.h

[b158f5]: Merge branch 'bug-8753-mitk-micro-services-2'

  • bug-8753-mitk-micro-s

Merged commits:

2011-09-06 09:26:23 Sascha Zelzer [fe62dd]
Do not introduce cyclic dependencies.

[3757c2]: Merge branch 'bug-8753-mitk-micro-services-2'

  • bug-8753-mitk-micro-s

Merged commits:

2011-09-11 17:51:30 Sascha Zelzer [fd42c5]
Added missing include for preprocessor defines

[b40465]: Merge branch 'bug-8753-mitk-micro-services-2'

Merged commits:

2011-09-18 16:55:20 Sascha Zelzer [ff6d6b]
Explicitly delete heap objects during static deinitialization.

[fd6d5b]: Merge branch 'bug-8753-mitk-micro-services-2'

  • bug-8753-mitk-micro-s

Merged commits:

2011-10-31 14:34:47 Sascha Zelzer [723310]
Added snippet for singleton service use.


2011-10-31 14:34:14 Sascha Zelzer [9ddd0d]
Use more generic way to set-up include and lib paths for snippets.


2011-10-31 14:33:24 Sascha Zelzer [676778]
Check for absolute paths of snippet source files.


2011-10-31 14:32:12 Sascha Zelzer [1800b9]
Fix retrieving symbol handles from the executable.


2011-10-31 14:31:11 Sascha Zelzer [42fd63]
Minimize locking of code to avoid recursive locks.


2011-10-27 11:24:59 Sascha Zelzer [3152de]
Fixed ServiceRegistration copy constructor.


2011-10-27 11:22:33 Sascha Zelzer [96e18f]
Fixed bad any_cast.


2011-10-27 17:45:35 Sascha Zelzer [216390]
Use consistent naming for "unlocked" methods.


2011-10-27 11:21:08 Sascha Zelzer [1dd079]
Avoid recursively locking non-recursive mutexes.

[4c8eb3]: Merge branch 'bug-8753-mitk-micro-services-2'

  • bug-8753-mitk-micro-s

Merged commits:

2011-11-01 21:00:23 Sascha Zelzer [fb91e1]
COMP: Added missing include for certain compilers

Reopened to solve a bug concerning the unloading of the "Mitk" library.

[a67c4f]: Merge branch 'bug-8753-activator-unload-not-called'

  • bug-8753-activa

Merged commits:

2011-12-04 11:36:21 Sascha Zelzer [f21418]
Call "Unload" of the Mitk Core activator explicitly.


2011-12-04 11:35:32 Sascha Zelzer [a0fb7a]
Added test to verify if "Unload" was called during library unloading.

[feb220]: Merge branch 'bug-8753-fix-service-reference-leaks'

  • bug-8753-fix-se

Merged commits:

2011-12-11 23:51:32 Sascha Zelzer [589281]
Break cyclic dependency by explicitly setting ref to 0.


2011-12-11 23:51:13 Sascha Zelzer [f28a0c]
Removed unnecessary null check.


2011-12-11 23:50:50 Sascha Zelzer [d2df65]
Check for null pointer prior to modifying the ref count.


2011-12-11 23:50:13 Sascha Zelzer [5bfbb0]
Disable copy constructor and assignment operator.

[51b9cb]: Merge branch 'bug-8753-mitk-micro-services-2'

  • bug-8753-mitk-micro-s

Merged commits:

2012-01-04 21:13:07 Sascha Zelzer [3767bb]
Use non-const parameter to avoid casting

The micro services infrastructure has been introduced and no new bugs appeared so far.

[9453c8]: Merge branch 'bug-8753-mitk-micro-services-2'

Merged commits:

2012-02-07 09:20:39 Sascha Zelzer [f55070]
Use MITK_DEBUG instead of MITK_INFO.