ThreadPool hanging in DLLs

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.

There seems to be a lot of little changes in that proposed patch. Which are necessary to address the “race condition”?

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.

What about the approach that was used for the ObjectFactoryBase:

Would having a separate object which is deconstructed when the code is unloaded help?

Also keep in mind that issues when there are duplicate symbols in ITK:

Great suggestion Brad! I will try that, probably next week.

I tried it and it doesn’t work. Here is my attempt:

static ThreadPool::Pointer m_ThreadPoolInstance;

class CleanUpThreadPool
    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.

Bug 3575 has been fixed by this commit:

1 Like