CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Jun 2010
    Posts
    3

    aitForSingleObject exit for timeout only, thread is not signaled

    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 Borland 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 <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)
    {
    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 );
    }
    Last edited by Steve R Jones; August 22nd, 2014 at 04:09 AM.

  2. #2
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: aitForSingleObject exit for timeout only, thread is not signaled

    Your problem is: thread does not actually unload on kernel level until dll process detach completed. See the sample when ThreadDestroy is called before freeing library - the thread exit gets detected fine.
    Attached Files Attached Files
    Last edited by Igor Vartanov; June 23rd, 2010 at 12:05 PM.
    Best regards,
    Igor

  3. #3
    Join Date
    Jun 2010
    Posts
    3

    Re: WaitForSingleObject exit for timeout only, thread is not signaled

    Igor,

    thank you for your reply.
    In your opinion, do you think there might be a clean solution relying only on FreeLibrary, i.e. doing everything that is needed to exit the thread and detect thread exit when the DLL is unloaded, or the only solution is telling the DLL user to call a specific DLL function before unloading the DLL with FreeLibrary?

  4. #4
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: WaitForSingleObject exit for timeout only, thread is not signaled

    Frankly, your sample is evidently artificial, and it's hard to say what exact scenario you do expect in a field. For example, I don't see any good in running the thread initially suspended and resume it anyway after a couple of CPU cycles. And the same way I do not understand why you should wait for thread quit. Is it just for paranoidly killing it?

    On the other hand, in case this would be some SDK dll, it seems absolutely normal to instruct its user to (un)initialize it at a proper moment.
    Best regards,
    Igor

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured