BUG: Restore functioning of CLI loadable module by fixing ITKv4 regression
Problem is summarize by the discussion posted on the ITK developer list
reported below.
// --------------
Question from Jean-Christophe Fillion-Robin:
Following commit 4c47e7d [1] of February 19th and commit defb9c1 [2] of
March 1st, due to static initialization, the initialization of
ObjectFactory now happens when ITK shared library are loaded [3][4].
This caused a regression in Slicer where the ObjectFactory were expected
to be loaded while attempting to load an image for the first time.
In Slicer case, the environment variable ITK_AUTOLOAD_PATH was set during
the initialization of the qSlicerCoreApplication, which is now too late.
By commenting line where a new ImageRegionSplitterSlowDimension is
instantiated [5][6] and updating the method "GetImageRegionSplitter /
GetGlobalDefaultSplitter" to return 0 [7][8], the initialization can
happen on demand instead of when ITK libraries are loaded.
An easy solution for us would be to ensure the "ITK_AUTOLOAD_PATH"
environment variable is set in the application launcher for Windows
and Linux application and set in Info.plist file associated with
the application bundle on MacOSX [9]
To provide more details, within Slicer we set the CMake variable
ITK_NO_IO_FACTORY_REGISTER_MANAGER before doing an
"include(${ITK_USE_FILE}) so that IOFactory are loaded only by
calling the method "itkFactoryRegistration" associated with a
shared library we named ITKFactoryRegistration. This approach allowed
us to disable the automatic registration of factory in selected part of
the code. More details here [10]
It seems the new ITK commits 4c47e7d and defb9c1 prevent from completely
leveraging the use of ITK_NO_IO_FACTORY_REGISTER_MANAGER variable, the
code should probably be updated to consider this.
[1] https://github.com/Kitware/ITK/commit/4c47e7d
[2] https://github.com/Kitware/ITK/commit/defb9c1
[3] https://github.com/Kitware/ITK/blob/4c47e7d672bad5d83b92c2df5f293cca618e2740/Modules/Core/Common/src/itkImageSource.cxx#L27
[4] https://github.com/Kitware/ITK/blob/4c47e7d672bad5d83b92c2df5f293cca618e2740/Modules/Core/Common/src/itkObjectFactoryBase.cxx#L142-144
[5] https://github.com/Kitware/ITK/blob/defb9c1d084c8d55df61947587427839f9968ecf/Modules/IO/ImageBase/src/itkImageIOBase.cxx#L760
[6] https://github.com/Kitware/ITK/blob/4c47e7d672bad5d83b92c2df5f293cca618e2740/Modules/Core/Common/src/itkImageSource.cxx#L27
[7] https://github.com/Kitware/ITK/blob/defb9c1d084c8d55df61947587427839f9968ecf/Modules/IO/ImageBase/src/itkImageIOBase.cxx#L765
[8] https://github.com/Kitware/ITK/blob/4c47e7d672bad5d83b92c2df5f293cca618e2740/Modules/Core/Common/src/itkImageSource.cxx#L32
[9] http://www.herzbube.ch/blog/2009/01/how-set-environment-variables-mac-os-x-applications
[10] https://github.com/Slicer/Slicer/commit/03b8961
// --------------
// --------------
Answer from Brad Lowekamp:
This is quite an interesting side-effect of the changes I introduced.
I am glad that you were able to figure this out. For a variety of
reasons, it's likely a very bad thing for all that to occur during
static initialization in ITK. So it certainly needs to be fixed.
I agree that lazy initialization is the way to go. Unfortunately it
needs to be thread safe so its a little more completed.
ITKv4 performs the factory initialization when the user creates the
first ITK object. And that changed with this patch, and need to be
fixed.
CONCLUSION:
Inside ITK, we can not use statically initialized ITK object.
// --------------
Issues:
http://www.na-mic.org/Bug/view.php?id=3042
http://www.na-mic.org/Bug/view.php?id=3008
ITK discussion:
http://comments.gmane.org/gmane.comp.lib.itk.devel/1133
ITK patch:
http://itk.org/gitweb?p=ITK.git;a=commit;h=1679816baef6b95356d9afdd9bd4a481ca08556c
http://review.source.kitware.com/#/c/10645/
Fixes 0003008
Fixes 0003042
git-svn-id: http://svn.slicer.org/Slicer4/trunk@21859 3bd1e089-480b-0410-8dfb-8563597acbee |