DllMain Thread Deinitialization

I came across an interesting issue with Windows dll loading/unloading capabilities. The issue is that Windows does not return from an EndThread/ExitThread/TerminateThread when DllMain is running until it’s done. This causes some interesting issues with the Delphi TThread class, which waits for the thread to be terminated to free it, so when a thread is freed from the finalization section of a unit in a dll, it will indefinitely wait. It’s not possible to use FreeOnTerminate instead and keep it running. This would leave the thread running in address space that doesn’t exist anymore.

There is no real workaround except changing the source code of TThread to stop waiting just before it reaches the ThreadProc’s EndThread or writing your own TThread class. In writing a solution for use in the RemObjects SDK we had several problems. Obviously we couldn’t change the Classes unit on every Delphi installation the ROSDK was installed. Another problem was that we support Delphi 6 and that doesn’t expose a static Synchronize method, so the class had to descend from TThread. We had to do, what I consider one of the worst hacks but it looked like it was the only way. We reintroduced WaitFor, implemented it so it would return right before the thread was calling ExitThread, using a Windows event. After that we introduced a method to wait for it to finish and free it so it mimicked the existing behavior of the TThread destructor.