Reputation: 432
Am in the process of migrating my project to the c++11 standard with msvc110, unfortunately a thread variable, used on a dll, is behaving different from what the boost version I had.
So, originally this was working on msvc90, basically the Dll calls an InitDll where a thread was created. The thread basically served as a listener along with the main thread of the dll. Now when I create the thread it hangs and does nothing, not even executing the function which was used to initialize the thread.
Could you help me explaining how can I get same behavior as for the boost version?
EDIT: THE CODE
Sorry, couldn't reply the code on the comments
An application uses a logger through a dll. To use the logger in a very simple console application goes like this
#include <Somewhere/Logger.h>
int main()
{
COOL_LOGGER("Here we go logging on console!");
return 0;
}
We can discuss about the way the code is written (taken from the demos I mentioned), but how is initialized the dll and thread is:
#include "Logger.h"
#ifdef _WIN32
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
TheLog::InitLog();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#endif
#include <thread>
void InitLog()
{
// Do the init taken from library demos
std::thread m_thread(LogListener);
}
void LogListener()
{
while(!bAppEnd)
{
std::cin>>str;
// change log behavior according to the user input
}
}
// to stop the thread when shutting down
void EndLog()
{
// retrieve thread thought id or some other way
thread.join();
}
Upvotes: 1
Views: 1358
Reputation: 68561
If things go wrong in DllMain
then you are severely limited in what you can do --- often the Windows loader will just terminate the app, and error handlers are often not called.
A hang suggests that the code is doing something that requires loading a DLL, or is waiting for another DLL to initialize, neither of which can happen until the call to DllMain
for this DLL is finished. It is possible that the implementation of std::thread
is doing one of these things.
Edit: One way to avoid the problem is to use std::call_once
in every exported function that communicates with this background thread, to ensure that the thread is started. That way you are not using std::thread
in DllMain
, but you don't need to expose an "init" function.
Upvotes: 3
Reputation: 6332
Your InitLog function has a thread that appears scoped to that function. When the function exits, which it does immediately, the thread is destroyed. However, destruction of an unjoined std::thread (but not boost::thread?) calls std::terminate. Put in a terminate handler if you want to test that that's what's happening.
Upvotes: 2