I have thread A that is creating another thread B, than thread A is waiting using WaitForSingleObject to wait until thread B dies.
The problem is that even though thread B returns from the thread's "thread_func", thread A does not get signaled!.
I know that because I added traces (OutputDebugString) to the end of the thread_func (thread B's main function) and I can see that thread B finishes its execution, but thread A never comes out of the WaitForSingleObject.
Now, I must also add that this code is in a COM object, and the scenario described above is happening when I'm calling regsvr32.exe (it get stuck!), so I believe that thread A is coming from the DLLMain.
Any ideas why thread A does not get signaled ?!?!
You could be hitting a problem with the loader lock. Windows, has an internal critical section that gets locked whenever a DLL is loaded/unloaded or when thread is started/stopped (DllMain is always called inside that lock). If your waiting thread A has that critical section locked (i.e. you are waiting somewhere from DllMain), while another thread B tries to shutdown and attempts to acquire that loader critical section, you have your deadlock.
To see where the deadlock happens, just run your app from the VS IDE debugger and after it gets stuck, break execution. Then look at all running threads, and note the stack of each one. You should be able to follow each stack and see what each thread is waiting on.
I think @DXM is right. The documentation on exactly what you can or can't do inside of DllMain
is sparse and hard to find, but the bottom line is that you should generally keep it to a bare minimum -- initialize internal variables and such, but that's about it.
The other point I'd make is that you generally should not "call" regsvr32.exe -- ever.
RegSvr32 is basically just a wrapper that loads a DLL into its address space with LoadLibrary
, Calls GetProcAddress
to get the address of a function named DllRegisterServer
, then calls that function. It's much cleaner (and ultimately, easier) to do the job on your own, something like this:
HMODULE mod = LoadLibrary(your_COM_file);
register_DLL = GetProcAddress(mod, "DllRegisterServer");
if ( register_DLL == NULL) {
// must not really be a COM object...
}
if ( S_OK != register_DLL()) {
// registration failed.
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With