Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Thread not signaled (WaitForSingleObject exit for timeout only)

faghiofaghio Member Posts: 1
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 could send a sample C++ builder project 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:

#include
#include

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)
{
while (MyThreadEnable)
{
DebugMess("Thread running...");
keybd_event(VK_SCROLL, 0, 0, 0);
Sleep(500);
keybd_event(VK_SCROLL, 0, KEYEVENTF_KEYUP, 0);
Sleep(500);
}

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, 5000))
{
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)
{
ThreadCreate();

if (MyThreadHandle)
{
ResumeThread(MyThreadHandle);
}
else
{
DebugMess("Thread creation failed");
}
}

void _DllTimerProcessDetach(void)
{
ThreadDestroy();
}

void _DllTimerThreadAttach(void)
{
}

void _DllTimerThreadDetach(void)
{
}


And the DllEntryPoint function:

#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 );
}




Sign In or Register to comment.