Hello everybody,
I am working with a thread for implementing a timer. If the thread is started / exited directly from an application (standard exe) everything works fine, but if I create and exit it from within a DLL loaded by the application, WaitForSingleObject fails to detect the thread exit. Why is that?
WaitForSingleObject exits with WAIT_TIMEOUT after 5 seconds instead of WAIT_OBJECT_0 (the one that I expect) and then I am forced to kill the thread with
TerminateThread.
I used the scroll key LED and Dbgview (OutputDebugString) for debugging.
In case someone were so kind to help me I attached a sample C++ builder project (sources only) with the code below (including a testing console for loading / unloading the DLL library).
Anyone can help?
Thank you very much in advance!!!!!!
Here is the code:
And the DllEntryPoint function:Code:#include <windows.h> #include <stdio.h> HANDLE MyThreadHandle = NULL; DWORD MyThreadId = 0; bool MyThreadEnable = false; void DebugMess(char *sMess) { char sDbg[257]; sprintf(sDbg, "PID=%04x,TID=%04x: %s", GetCurrentProcessId(), GetCurrentThreadId(), sMess); OutputDebugString(sDbg); } DWORD WINAPI ThreadFunction(void *unused) { DebugMess("Thread loop enter"); while (MyThreadEnable) { DebugMess("Thread running..."); keybd_event(VK_SCROLL, 0, 0, 0); Sleep(500); keybd_event(VK_SCROLL, 0, KEYEVENTF_KEYUP, 0); Sleep(500); } DebugMess("Thread loop exit"); return 0; } void ThreadCreate(void) { SECURITY_ATTRIBUTES saAttr; if (MyThreadHandle == NULL) { saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = true; saAttr.lpSecurityDescriptor = NULL; MyThreadHandle = CreateThread ( &saAttr , 0 , ThreadFunction , (LPVOID) NULL , CREATE_SUSPENDED , &MyThreadId ); if (MyThreadHandle != NULL) { MyThreadEnable = true; } } return; } void ThreadDestroy(void) { if (MyThreadHandle) { /* Exit from loop */ MyThreadEnable = false; /* Wait thread exit */ switch (WaitForSingleObject(MyThreadHandle, 1000)) { case WAIT_OBJECT_0 : { DebugMess("Thread ended OK"); break; } case WAIT_TIMEOUT : { DebugMess("WaitForSingleObject - timeout"); TerminateThread(MyThreadHandle, 0); break; } default : { DebugMess("WaitForSingleObject - other"); TerminateThread(MyThreadHandle, 0); break; } } keybd_event(VK_SCROLL, 0, KEYEVENTF_KEYUP, 0); CloseHandle(MyThreadHandle); MyThreadHandle = NULL; MyThreadId = 0; } } void _DllTimerProcessAttach(void) { DebugMess("Attaching process..."); ThreadCreate(); if (MyThreadHandle) { ResumeThread(MyThreadHandle); } else { DebugMess("Thread creation failed"); } } void _DllTimerProcessDetach(void) { DebugMess("Detaching process..."); ThreadDestroy(); } void _DllTimerThreadAttach(void) { DebugMess("Attaching thread..."); } void _DllTimerThreadDetach(void) { DebugMess("Detaching thread..."); }
and the log file:Code:#pragma argsused int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { int iDllProcess; switch ( reason ) { case DLL_THREAD_ATTACH : { _DllTimerThreadAttach(); iDllProcess = 1; break; } case DLL_THREAD_DETACH : { _DllTimerThreadDetach(); iDllProcess = 1; break; } case DLL_PROCESS_ATTACH : { _DllTimerProcessAttach(); iDllProcess = 1; break; } case DLL_PROCESS_DETACH : { _DllTimerProcessDetach(); iDllProcess = 1; break; } } return ( iDllProcess ); }
00000000 0.00000000 [3996] PID=0f9c,TID=0ff4: Attaching process...
00000001 0.00010768 [3996] PID=0f9c,TID=0ff8: Attaching thread...
00000002 0.00017417 [3996] PID=0f9c,TID=0ff8: Thread loop enter
00000003 0.00022960 [3996] PID=0f9c,TID=0ff8: Thread running...
00000004 0.99959105 [3996] PID=0f9c,TID=0ff8: Thread running...
00000005 1.99953830 [3996] PID=0f9c,TID=0ff8: Thread running...
00000006 2.99953294 [3996] PID=0f9c,TID=0ff8: Thread running...
00000007 3.99991632 [3996] PID=0f9c,TID=0ff8: Thread running...
00000008 4.99960756 [3996] PID=0f9c,TID=0ff8: Thread running...
00000009 5.99944973 [3996] PID=0f9c,TID=0ff8: Thread running...
00000010 6.99947405 [3996] PID=0f9c,TID=0ff8: Thread running...
00000011 7.73600912 [3996] PID=0f9c,TID=0ff4: Detaching process...
00000012 7.99939489 [3996] PID=0f9c,TID=0ff8: Thread loop exit
00000013 12.73392105 [3996] PID=0f9c,TID=0ff4: WaitForSingleObject - timeout
If I make a DLL function for closing the thread (which calls ThreadDestroy) instead of doing that at process detach (with FreeLibrary), it works, but I would like not to have to call a specific uninitialize function and do everything just with FreeLibrary.



LinkBack URL
About LinkBacks


