InsightSoftwareConsortium / InsightSoftwareConsortium/ITK

Improve C++ Factory Static Initialization Coverage

Open
#3,301 3 comments 0 reactions 0 assignees View on GitHub
type:Coverage
Dominant language
C++
Stars
1.7k
Forks
748
Avg merge
1d 1h
Merged PRs (30d)
64

Description

### Overview

C++ factory initialization coverage should be expanded.

### Background

Issue #3156 changed how object factory registrations worked in Python.

Previous behavior:
- C++ modules rely on magic static initialization to register factory overrides when libraries are loaded
- Python modules also rely on static initialization for registering factories when ITK module libraries are lazily loaded

For purposes of allowing consuming project to populate factory lists with their own factory definitions, static initialization is not performed until a consuming includes `UseITK.cmake` in the configuration step. Since ITK Python did this, it was reasonable at the time to use successful ITK Python building as a stand-in for explicit coverage. However, static initialization behavior led to an issue observed in 3D Slicer where two different ITK Python versions may try to reference the same static object in memory, causing a crash. The resolution to this was to use Python initialization mechanisms instead of C++ static initialization to register one Python factory object at a time.

New behavior:
- C++ modules rely on magic static initialization to register factory overrides
- Python modules rely on explicit factory instantiation and registration in ITK Python recursive lazy loading mechanisms

Updated Python behavior is covered in tests under `Wrapping/Generators/Python/Tests`. However, as ITK Python no longer relies on the same C++ static initialization mechanism, static initialization is not currently covered.

### Proposal

In order to test C++ static initialization it is necessary to define a test project consuming `UseITK.cmake` and ensure that factories are loaded correctly.

In #3156 the simple [HelloWorld](https://github.com/InsightSoftwareConsortium/ITK/tree/master/Examples/Installation) test project is referenced as an example of a nightly build that tests that projects may consume ITK correctly. It would be useful to either expand this project or duplicate its nightly build process in order to ensure that factories are registered correctly.

### Steps to Cover

Static initialization involves a few steps.
- The user specifies whether static initialization should be turned off or on with flags such as `ITK_NO_IMAGEIO_FACTORY_REGISTER_MANAGER`. These are off for ITK Python. These should be explicitly set to ON for static initialization test coverage.
- At CMake generation files such as `ImageIOFactoryRegisterManager.h` are configured to contain a list of free functions to call at static initialization. The file also defines a global instance of the register manager, whose constructor will in turn call each free function for initialization.
- Modules with factory overrides must also implement the respective free function that will be configured and called in the `FactoryRegisterManager` file. These are typically found in a file in the `src` folder with the postfix `__Private`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.