Click here to Skip to main content
15,868,016 members
Articles / Desktop Programming / MFC
Article

Thread pool class Bug Fixed

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
24 Aug 20021 min read 54.5K   10   5
Fixed a bug about Thread pool class submited by Sherwood Hu

Thread pool

Last week I find those cool code shared by Sherwood Hu. You can view the article named "A programming model to use a thread pool" for details of this class. I used this class to boot the performance of my application. But a strange phenomenon puzzled me for a long time. That is: it works perfectly when I run my application normally, but suspends sometimes when I debug my application. I located the bug finally after some "Ctrl+Alt+Del". Check the original code here:

unsigned int CThreadPool::ManagerProc(void* p)
{
    //convert the parameter to the server pointer.
    CThreadPool* pServer=(CThreadPool*)p;
    HANDLE    IoPort    = pServer->GetMgrIoPort();
    unsigned long pN1, pN2; 
    OVERLAPPED* pOverLapped;

LABEL_MANAGER_PROCESSING:
    while(::GetQueuedCompletionStatus(IoPort, &pN1, &pN2, 
        &pOverLapped, pServer->GetMgrWaitTime() ))
    {
        if(pOverLapped == (OVERLAPPED*)0xFFFFFFFF)
            break;
        else
        {
            TRACE0("mgr events comes in!\n");
        }
    }

    //time out processing
    if (::GetLastError()==WAIT_TIMEOUT)
    {
        //time out processing
        TRACE0("Time out processing!\n");
        //the manager will take a look at all the worker's status. The
        if (pServer->GetThreadPoolStatus()==CThreadPool::BUSY)
            pServer->AddThreads();
        if (pServer->GetThreadPoolStatus()==CThreadPool::IDLE)
            pServer->RemoveThreads();

        goto LABEL_MANAGER_PROCESSING;
    }
    return 0;
}

The CThreadPool::Stop function uses:

::PostQueuedCompletionStatus(m_hMgrIoPort, 0, 0, (OVERLAPPED*)0xFFFFFFFF);

to stop the manager thread. The manager thread uses:

::GetQueuedCompletionStatus(IoPort, &pN1, &pN2, 
         &pOverLapped, pServer->GetMgrWaitTime())

to wait this message. When it meets the condition:

pOverLapped == (OVERLAPPED*)0xFFFFFFFF)

the thread stops normal. While this API wait times out, it uses "goto" continue waiting. Quit message and timeout event may not occur if the program runs normally, but it may occur when you debug your code. The manager thread will receive the quit message and timeout event at the same time while you insert the break point in your code and trace it step by step. The manager thread receives the quit message and breaks from while circulation, but is caught by the following if statement and throw to begin by "goto" statement. Since it will never receive quit message again, it will circulate endless. So the application will suspend at here:

void CThreadPool::Stop(bool bHash)
{
......
    WaitForSingleObject(m_hMgrThread, INFINITE);//program will suspend here
......
}

Solution

I add a sign to distinguish the quit message and timeout event, and thus the bug is fixed.

.....
    BOOL bExit = FALSE;
LABEL_MANAGER_PROCESSING:
    while(::GetQueuedCompletionStatus(IoPort, &pN1, &pN2, 
        &pOverLapped, pServer->GetMgrWaitTime() ))
    {
        if(pOverLapped == (OVERLAPPED*)0xFFFFFFFF)
        {
            bExit = TRUE; 
            break;
        }
        else
        {
            TRACE0("mgr events comes in!\n");
        }
    }

    //time out processing
    if (::GetLastError()==WAIT_TIMEOUT && !bExit)
    {
......

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
China China
I had graduated from HuaZhong University of Science & Technology. Now, I'm working in ZTE.

Comments and Discussions

 
GeneralThread pool fix Pin
Mike Junkin26-Aug-02 8:10
Mike Junkin26-Aug-02 8:10 
XSimon,

There are many problems with the code in Hu's thread pool class. Ranging from minor stylistic problems - like the goto and poorly named variables - to more serious problems like not properly evaluating the return from GetQueuedCompletionStatus() and not using try/catches around critical code.

The code might be useful as an introduction to thread pool concepts but you should be very careful about using it for anything more.

Mike
GeneralRe: Thread pool fix Pin
Simon.W26-Aug-02 18:18
Simon.W26-Aug-02 18:18 
GeneralRe: Thread pool fix Pin
Anthony_Yio5-Jan-03 23:42
Anthony_Yio5-Jan-03 23:42 
GeneralRe: Thread pool fix Pin
Mushica4-Jun-03 14:26
sussMushica4-Jun-03 14:26 
GeneralRe: Thread pool fix Pin
Simon.W6-Jun-03 1:26
Simon.W6-Jun-03 1:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.