I know I cannot create threads from DllMain, but what is the correct approach for creating threads in a DLL?
I tried to create a class that wraps around it and declare a global instance of that class, but then WaitForSingleObject hangs in the destructor of the class, even though I'm certain that the thread has exited.
Here is my sample program to load the dll from an exe:
#include <Windows.h>
#include <iostream>
using namespace std;
int main(int argc, TCHAR* argv[])
{
HMODULE module = LoadLibraryA("dll.dll");
Sleep(500);
if (module) FreeModule(module);
else cout << "failed to load library...\n";
return 0;
}
And here is the dll code:
#include <Windows.h>
#include <iostream>
using namespace std;
class X
{
HANDLE thread = NULL;
static DWORD WINAPI run_thread(LPVOID param)
{
cout << "dll.cpp: thread started\n";
Sleep(1000);
cout << "dll.cpp: thread is exiting\n";
return 0;
}
public:
X()
{
DWORD tmp;
thread = CreateThread(NULL, 0, run_thread, NULL, 0, &tmp);
if (thread == NULL)
{
cout << "failed to create thread\n";
throw 1;
}
}
~X()
{
if (thread != NULL)
{
cout << "joining thread...\n";
DWORD ret = WaitForSingleObject(thread, INFINITE);
cout << "result from waiting: " << ret << "\n";
thread = NULL;
}
}
}x;
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
cout << __FUNCTION__ << " reason DLL_PROCESS_ATTACH\n";
break;
case DLL_THREAD_ATTACH:
cout << __FUNCTION__ << " reason DLL_THREAD_ATTACH\n";
break;
case DLL_THREAD_DETACH:
cout << __FUNCTION__ << " reason DLL_THREAD_DETACH\n";
break;
case DLL_PROCESS_DETACH:
cout << __FUNCTION__ << " reason DLL_PROCESS_DETACH\n";
break;
}
return TRUE;
}
This is the program output:
DllMain reason DLL_PROCESS_ATTACH
DllMain reason DLL_THREAD_ATTACH
dll.cpp: thread started
DllMain reason DLL_PROCESS_DETACH
joining thread...
dll.cpp: thread is exiting
<- notice how WaitForSingleObject hangs,
even though the thread has exited
What is wrong with this approach?
If I happen to remove the Sleep(1000) from run_thread, so that the thread finishes before WaitForSingleObject is called, then it does not hang:
DllMain reason DLL_PROCESS_ATTACH
DllMain reason DLL_THREAD_ATTACH
dll.cpp: thread started
dll.cpp: thread is exiting
DllMain reason DLL_THREAD_DETACH
DllMain reason DLL_PROCESS_DETACH
joining thread...
result from waiting: 0
I don't understand the difference, and that is also not an option, since the purpose of the thread is to loop constantly while DLL_PROCESS_DETACH is not signaled.