Click here to Skip to main content
15,891,136 members
Articles / Desktop Programming / MFC

WorkerThread Library

Rate me:
Please Sign up or sign in to vote.
4.00/5 (4 votes)
7 Nov 20054 min read 57.6K   990   35  
An article on a generic WorkerThread library.
#include "WorkerThread.h"
#include "WorkItem.h"

const UINT DO_WORK           = ::RegisterWindowMessage( _T("DO_WORK"));
const UINT EXIT_WORKERTHREAD = ::RegisterWindowMessage( _T("EXIT_WORKERTHREAD"));

IMPLEMENT_DYNCREATE(WorkerThread, CWinThread)

// Definition of Message Map
BEGIN_MESSAGE_MAP(WorkerThread, CWinThread)
    ON_REGISTERED_THREAD_MESSAGE( DO_WORK, OnDoWork )
    ON_REGISTERED_THREAD_MESSAGE( EXIT_WORKERTHREAD, OnExitThread )
END_MESSAGE_MAP()


/**
 *
 * Constructor initializes members
 *
 * @param       Nil
 * @return      Nil
 * @exception   Nil
 * @see         Nil
 * @since       1.0
 */
WorkerThread::WorkerThread(): m_bIdle( true )
{
    OutputDebugString( _T("Entering into WorkerThread::WorkerThread" ));
    try
    {
        // Set AutoDeletion feature to false to delete the thread forcefully
        CWinThread::m_bAutoDelete = FALSE;

        // Initialize Critical Section
        ::InitializeCriticalSection( &m_CriticalSection );
    }
    catch( ... )
    {
        OutputDebugString( _T("Exception in WorkerThread Constructor" ));
    }
    OutputDebugString( _T("Leaving from WorkerThread::WorkerThread" ));
}


/**
 *
 * Destructor destroys Critical section object
 *
 * @param       Nil
 * @return      Nil
 * @exception   Nil
 * @see         Nil
 * @since       1.0
 */
WorkerThread::~WorkerThread()
{
    OutputDebugString( _T("Entering into WorkerThread::~WorkerThread" ));
    try
    {
        // Delete Critical Section
        ::DeleteCriticalSection( &m_CriticalSection );
    }
    catch( ... )
    {
        OutputDebugString( _T("Exception in WorkerThread Destructor" ));
    }
    OutputDebugString( _T("Leaving from WorkerThread::~WorkerThread" ));
}


BOOL WorkerThread::InitInstance()
{
    return TRUE;
}

/**
 *
 * This function is called while posting the DO_WORK message from the
 * WorkerThreadMgr class.This function will call the DoWork() of
 * WorkItem class
 *
 * @param       wParam_i - Pointer to WorkItem Class
 * @param       lParam_i - Not Used
 * @return      LRESULT  - TRUE if no exception, else FALSE
 * @exception   Nil
 * @see         Nil
 * @since       1.0
 */
LRESULT WorkerThread::OnDoWork( WPARAM wParam_i, LPARAM lParam_i )
{
    OutputDebugString( _T("Entering into WorkerThread::OnDoWork" ));

    LRESULT lRet = TRUE;

    try
    {
        // Do work with WorkItem
        WorkItem* pItem = (WorkItem*) wParam_i;
        if( 0 != pItem )
        {
            // Set Thread Status as busy
            SetThreadIdleStatus( false );

            pItem->DoWork();

            // The Thread is now free after doing work
            SetThreadIdleStatus( true );

            delete pItem;
        }
        else
        {
            lRet = FALSE;
            OutputDebugString( _T("WorkItem is NULL" ));
        }
    }
    catch( ... )
    {
        lRet = FALSE;
        OutputDebugString( _T("Exception in WorkerThread::OnDoWork" ));
    }

    OutputDebugString( _T("Leaving from WorkerThread::OnDoWork" ));
    return lRet;
}


/**
 *
 * This is called while posting the EXIT_WORKERTHREAD message from
 * Terminate() function
 * This function will call AfxEndThread to exit the thread
 *
 * @param       wParam_i - Not Used
 * @param       lParam_i - Exit code of the thread
 * @return      LRESULT  - TRUE if no exception, else FALSE
 * @exception   Nil
 * @see         Nil
 * @since       1.0
 */
LRESULT WorkerThread::OnExitThread( WPARAM wParam_i, LPARAM lParam_i )
{
    OutputDebugString( _T( "Entering into WorkerThread::OnExitThread()" ));

    LRESULT lRet = TRUE;

    try
    {
        // Kills the threads
        AfxEndThread( lParam_i );
    }
    catch( ... )
    {
        lRet = FALSE;
        OutputDebugString( _T( "Exception in WorkerThread::OnExitThread()" ));
    }
    OutputDebugString( _T( "Leaving from WorkerThread::OnExitThread()" ));

    return lRet;
}


/**
 *
 * Checks whether the thread is idle or not
 * Synchronized using Critical section object
 * @param       Nil
 * @return      bool - true if thread is running, else false
 * @exception   Nil
 * @see         Nil
 * @since       1.0
 */
bool WorkerThread::IsIdle()
{
    OutputDebugString( _T("Entering into WorkerThread::IsIdle()" ));

    ::EnterCriticalSection( &m_CriticalSection );

    bool bIdle = m_bIdle;

    ::LeaveCriticalSection( &m_CriticalSection );

    OutputDebugString( _T( "Leaving from WorkerThread::IsIdle()" ));

    return bIdle;
}

/**
 *
 * Sets the status of the Worker thread
 * This function is synchronized using critical section object
 *
 * @param       bStatus_i - true indicates Thread is not running.
 *                          false indicates Thread is running.
 * @return      void
 * @exception   Nil
 * @see         Nil
 * @since       1.0
 */
void WorkerThread::SetThreadIdleStatus( bool bStatus_i )
{
    OutputDebugString( _T("Entering into WorkerThread::SetThreadIdleStatus()" ));

    ::EnterCriticalSection( &m_CriticalSection );

    m_bIdle = bStatus_i;

    ::LeaveCriticalSection( &m_CriticalSection );

    OutputDebugString( _T("Leaving from WorkerThread::SetThreadIdleStatus()" ));
}


/**
 *
 * This function will terminate the worker thread.
 * Called from WorkerThreadMgr
 *
 * @param       Nil
 * @return      bool - Status of the termination of the worker thread
 *                     true if success , else false
 * @exception   Nil
 * @see         Nil
 * @since       1.0
 */
bool WorkerThread::Terminate()
{
    OutputDebugString( _T("Entering into WorkerThread::Terminate()" ));

    bool bRet = true;
    try
    {
        PostThreadMessage( EXIT_WORKERTHREAD, 0, 0 );

        DWORD dwWait = ::WaitForSingleObject( this->m_hThread,
                                              TIMEOUT_PER_THREAD );
        if( WAIT_OBJECT_0 == dwWait  )
        {
            OutputDebugString( _T("WorkerThread termination event set Over" ));
        }
        else
        {
            OutputDebugString( _T("WorkerThread termination event set Failed" ));
        }
    }
    catch( ... )
    {
        bRet = false;
        OutputDebugString( _T("Exception in WorkerThread::Terminate()" ));
    }

    OutputDebugString( _T("Leaving from WorkerThread::Terminate()" ));

    return bRet;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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
Web Developer
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions