There is really no good solution to your problem, and, you should try
to have your APIs/functions to express an Initialize/Deinitialize paradigm.
First of all, creating a thread in DllMain is unsafe, because if your
DllMain returns FALSE, then, you may end-up unloading the module
while the thread is still executing.
Likewise, even if you succeed, your thread must acquire a reference
on the module (by either forcefully calling LoadLibrary,
or GetModuleHandleEx), to guarantee that nobody can make the thread
run on an unloaded module, by artificially calling FreeLibrary.
As a secondary item, synchronizing Dll-Termination and a thread shutdown
is almost always guarantee to get you into a loader lock deadlock,
because you are holding the loader lock in DllMain(PROCESS_DETACH)
and, you need the LoaderLock to call ExitThread.
The only paradigm that has a chance to work is an explicit
pair of functions, for each thread.
That is the way in which, for example, ws2_2/wsock32
does cleanup of worker threads, by using WSAStartup/WSACleanup
to count the number of outstanding users, and, separating the DLL-Lifetime
by the users lifetime. Other examples are CoInitialize/CoUninitialize,
that may optionally perform cleanup of extra worker thread created
to perform decoupling of inter-apartment calls.
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
Post by Bruce.
We have a DLL, very old, and being used by hundreds of applications. I'm
in the process of adding a maintenance thread (the first) to that DLL. It
has to be done in a way that won't require me changing hundreds of other
programs. Many of these are customer programs outside of my control.
I wrote the thread and am starting it when the DllMain is called with
DLL_PROCESS_ATTACH. So far so good.
The thread starts, runs, and everything works, until it's time to shut down.
I can't get the thread to gracefully exit. When the host exe exits,
Windows calls DllMain with DLL_PROCESS_DETACH. In that I set a terminate
flag for the thread to see, but thread in the dll doesn't run long enough
to see it, so it never completes, and never cleans up.
In researching this on the web, it turns out that DLL_PROCESS_DETACH isn't
called until after all process threads have already been halted,
ungracefully if necessary. That makes it sound impossible to signal the
thread at that time to have it exit.
So is there any good way to get the thread in a dll to gracefully exit
without modifying the exe's that use the dll?
Thanks for any help.