Johan discovered that ThreadPool causes the program to always hang on Windows if ITK is compiled as shared libraries. After trying to deal with it over the last few days, I created a MWE which does not depend on ITK and entered it in the bug tracker.
Does somebody know of an elegant solution to this problem? The ugly one is in this proposed patch.
Changes in the destructor are related to the bug workaround. The other changes are supposed to make threads play better with MSVC CRT library, and be more consistent with threading implementation in itkMultiThreader.
I tried it and it doesn’t work. Here is my attempt:
static ThreadPool::Pointer m_ThreadPoolInstance;
m_ThreadPoolInstance = ITK_NULLPTR; // removing last reference invokes the destructor
//NOTE: KWStyle insists on m_ for m_CleanUpThreadPoolGlobal
static CleanUpThreadPool m_CleanUpThreadPoolGlobal;
The destructors of both CleanUpThreadPool and SmartPointer are called at DllMain DLL_PROCESS_DETACH time, so this doesn’t help. Because ITKCommon.dll is being detached due to process termination, lpvReserved is non-NULL.
When handling DLL_PROCESS_DETACH, a DLL should free resources such as heap memory only if the DLL is being unloaded dynamically (the lpReserved parameter is NULL). If the process is terminating (the lpvReserved parameter is non-NULL), all threads in the process except the current thread either have exited already or have been explicitly terminated by a call to the ExitProcess function, which might leave some process resources such as heaps in an inconsistent state. In this case, it is not safe for the DLL to clean up the resources. Instead, the DLL should allow the operating system to reclaim the memory.