Listing 2: Class CWorkerThread definition and implementation

//
// partial listing of worker.h
//
class CThreadPool ;
typedef unsigned ( __stdcall * PFNTHREAD )( void * );
const int STOP_WORKER_THREAD = 1;

class CWorkerThread  {
public:
    CWorkerThread( CThreadPool* pPool );
    virtual ~CWorkerThread();

    CThreadPool* GetThreadPool() const;
    BOOL Start();
    BOOL IsThreadRunning() const;
    HANDLE GetThreadHandle() const;
    DWORD GetThreadID() const;

    virtual void OnReceivedCompletionPacket( BOOL bResult,
        DWORD dwNumberOfBytesTransferred, DWORD dwKey,
        LPOVERLAPPED lpOverlapped ) = 0;

protected:
    static int ThreadEntryProc( LPVOID pPooledThread );
    void Reset();
    virtual void ThreadMain();

 protected:
     CThreadPool* m_pThreadPool ;
    HANDLE    m_hThread;
    HANDLE    m_hStartEvent;
    DWORD    m_dwThreadID ;
    BOOL    m_bRunning;
};

/ -------------------------------------------------------------------
// Partial listing of worker.cpp

BOOL CWorkerThread::Start(void)
{
    if( IsThreadRunning() ) {
        return FALSE ;
    } // if

    assert( m_hStartEvent == INVALID_HANDLE_VALUE );
    m_hStartEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    m_hThread = reinterpret_cast<HANDLE>( 
        _beginthreadex( NULL, 0, 
            (PFNTHREAD)(CWorkerThread::ThreadEntryProc), this, 0,
            reinterpret_cast<unsigned int*>(&m_dwThreadID) ));

    WaitForSingleObject( m_hStartEvent, INFINITE );
    return TRUE ;
}

int CWorkerThread::ThreadEntryProc( LPVOID pThreadClass )
{
    assert(pThreadClass != NULL);
    ULONG nResult = 0;
    CWorkerThread* pThread = 
        static_cast<CWorkerThread*>(pThreadClass);

    assert( pThread->m_hStartEvent != INVALID_HANDLE_VALUE );
    pThread->m_bRunning = TRUE;
    SetEvent( pThread->m_hStartEvent );
 
    try {
        pThread->ThreadMain();
    } catch(...) {
        nResult = 1;
    } // catch

    pThread->m_bRunning = FALSE;
    _endthreadex( nResult );

    return 0 ;
}

void CWorkerThread::ThreadMain()
{
    while( TRUE ) {
        DWORD dwNumBytesTransferred = 0 ;
        DWORD dwKey = 0 ;
        LPOVERLAPPED lpOverlapped = NULL ;

        BOOL bResult = GetThreadPool()->GetQueuedCompletionStatus(
            &dwNumBytesTransferred, &dwKey, &lpOverlapped, 
            INFINITE );

        if( bResult == TRUE && dwKey == STOP_WORKER_THREAD ) {
            break ;
        } else {
            OnReceivedCompletionPacket( 
                bResult, dwNumBytesTransferred, dwKey, lpOverlapped);
        } // else
    } // while
}

/* End of File */