Thread: Thread not signaled (WaitForSingleObject exit for timeout only)

  1. #1
    Registered User
    Join Date
    Jun 2010
    Posts
    1

    Thread not signaled (WaitForSingleObject exit for timeout only)

    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:

    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 DllEntryPoint function:

    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 );
    }
    and the log file:

    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.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> WaitForSingleObject fails to detect the thread exit. Why is that?
    Because you are in the context of DllMain, and a thread handle will never change state in that context.

    An event does work in the context of DllMain, so use one event to signal the exit condition and another event to signal "I'm exiting".

    DLL Dynamic Link Library Best Practices

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help in C programming (too lazy)
    By cwillygs in forum C Programming
    Replies: 12
    Last Post: 04-20-2010, 12:23 AM
  2. How to make a thread sleep or std::recv timeout?
    By BrianK in forum Linux Programming
    Replies: 3
    Last Post: 02-26-2003, 10:27 PM
  3. Multithreading
    By Cela in forum Windows Programming
    Replies: 13
    Last Post: 01-15-2003, 03:02 PM
  4. MFC Controls and Thread Safety :: MFC
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 12-06-2002, 11:36 AM
  5. Multi-Thread Programming
    By drdroid in forum C++ Programming
    Replies: 6
    Last Post: 04-04-2002, 02:53 PM

Tags for this Thread